package com.aizuda.boot.modules.business.template.service.impl;

import com.aizuda.boot.modules.business.contract.entity.*;
import com.aizuda.boot.modules.business.contract.service.*;
import com.aizuda.boot.modules.business.contract.service.ContractTypeDepartmentService;
import com.aizuda.boot.modules.business.contract.entity.ContractTypeDepartmentEntity;
import com.aizuda.boot.modules.business.contract.service.ContractTypeUserService;
import com.aizuda.boot.modules.business.contract.entity.ContractTypeUser;
import com.aizuda.boot.modules.business.contract.entity.dto.LoginCheckVO;
import com.aizuda.boot.modules.business.contract.dto.SingleResponse;
import com.aizuda.boot.modules.common.constant.enums.ResponseCodeEnum;
import com.aizuda.boot.modules.flw.entity.FlwProcessConfigure;
import com.aizuda.boot.modules.flw.service.IFlwProcessConfigureService;
import com.aizuda.boot.modules.flw.service.IFlwFormTemplateService;
import com.aizuda.boot.modules.flw.entity.FlwFormTemplate;
import com.aizuda.bpm.mybatisplus.mapper.FlwProcessMapper;
import com.aizuda.bpm.engine.entity.FlwProcess;
import com.aizuda.common.toolkit.JacksonUtils;
import com.aizuda.core.api.ApiAssert;
import com.alibaba.fastjson.JSON;
import com.aizuda.boot.modules.file.service.IFileInfoService;
import com.aizuda.boot.modules.system.service.ISysUserService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;
import com.aizuda.boot.modules.business.employee.domain.request.EmployeeQueryById;
import com.aizuda.boot.modules.business.employee.domain.response.EmployeeQueryShowVO;
import com.aizuda.boot.modules.business.contract.entity.ContractTypeEntity;
import com.aizuda.boot.modules.business.performance.mapper.ContractTypeMapper;
import com.aizuda.boot.modules.business.template.mapper.ContractTemplateUsageMapper;
import com.aizuda.boot.modules.file.domain.vo.FileVO;
import com.aizuda.boot.modules.file.domain.vo.FileUploadVO;
import com.aizuda.boot.modules.business.template.entity.ContractTemplateEntity;
import com.aizuda.boot.modules.business.template.entity.ContractTemplateFieldEntity;
import com.aizuda.boot.modules.business.template.entity.ContractTemplateUsageEntity;
import com.aizuda.boot.modules.business.template.entity.TemplateDefaultFieldDetailEntity;
import com.aizuda.boot.modules.business.template.entity.dto.ContractTemplateAddReqDTO;
import com.aizuda.boot.modules.business.template.entity.vo.ContractTemplateDraftListRespDTO;
import com.aizuda.boot.modules.business.template.entity.vo.ContractTemplateRespDTO;
import com.aizuda.boot.modules.business.template.entity.vo.ContractTemplatesByTypeRespDTO;
import com.aizuda.boot.modules.business.contract.entity.vo.ContractFormDataDTO;
import com.aizuda.boot.modules.business.template.mapper.ContractTemplateFieldMapper;
import com.aizuda.boot.modules.business.template.mapper.ContractTemplateMapper;
import com.aizuda.boot.modules.business.template.mapper.TemplateDefaultFieldDetailMapper;
import com.aizuda.boot.modules.business.template.service.ContractTemplateService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.InputStream;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.business.contract.dto.UserInfo;
import com.aizuda.boot.modules.business.department.service.DepartmentService;
import com.aizuda.boot.modules.business.contract.entity.ContractWorkflowDepartment;
import com.aizuda.boot.modules.business.contract.service.ContractWorkflowDepartmentService;
import com.aizuda.bpm.mybatisplus.mapper.FlwExtInstanceMapper;
import com.aizuda.boot.modules.system.service.ISysUserDepartmentService; // 仅用于工作流选择，不用于模板列表权限判定

/**
 * 合同模版Service实现类
 */
@Slf4j
@Service
public class ContractTemplateServiceImpl extends ServiceImpl<ContractTemplateMapper, ContractTemplateEntity> implements ContractTemplateService {

    @Resource
    private ContractTemplateMapper contractTemplateMapper;

    @Resource
    private ContractTemplateFieldMapper contractTemplateFieldMapper;

    @Resource
    private TemplateDefaultFieldDetailMapper templateDefaultFieldDetailMapper;

    @Resource
    private ContractTemplateUsageMapper contractTemplateUsageMapper;

    @Resource
    private ContractTypeMapper contractTypeMapper;

    @Resource
    private ContractWorkflowTypeService contractWorkflowTypeService;

    @Resource
    private ContractWorkflowFormFieldService contractWorkflowFormFieldService;

    @Resource
    private ContractWorkflowService contractWorkflowService;

    @Resource
    private IFlwProcessConfigureService flwProcessConfigureService;

    @Resource
    private ContractModuleService contractModuleService;

    @Resource
    private ContractFieldService contractFieldService;

    @Resource
    private ContractModuleFieldService contractModuleFieldService;

    @Resource
    private IFileInfoService fileInfoService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysUserDepartmentService sysUserDepartmentService; // 仅用于工作流选择，不用于模板列表权限判定
    
    @Resource
    private ContractWorkflowDepartmentService contractWorkflowDepartmentService;

    @Resource
    private ContractTypeDepartmentService contractTypeDepartmentService;

    @Resource
    private ContractTypeUserService contractTypeUserService;

    @Resource
    private FlwProcessMapper flwProcessMapper;

    @Resource
    private IFlwFormTemplateService flwFormTemplateService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private FlwExtInstanceMapper flwExtInstanceMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addOrUpdateTemplate(ContractTemplateAddReqDTO dto) {
        // 如果前端没有传递templateFileId，上传空白Word文档
        if (dto.getTemplateFileId() == null) {
            try {
                log.info("前端未传递templateFileId，开始上传空白Word文档");
                
                // 获取当前用户信息
                UserInfo currentUser = AuthUtil.getCurrentUser();
                if (currentUser == null) {
                    log.error("无法获取当前用户信息，跳过文件上传");
                } else {
                    // 上传空白Word文档到模版文件夹(文件夹类型5)
                    SingleResponse<FileUploadVO> uploadResult = uploadBlankWordDocument(currentUser);
                    
                    if (uploadResult.isSuccess() && uploadResult.getData() != null) {
                        // 获取上传后的新文件ID
                        Long newFileId = uploadResult.getData().getFileId();
                        // 将Long类型的文件ID转换为Integer类型并赋值给templateFileId
                        dto.setTemplateFileId(newFileId.intValue());
                        log.info("成功上传空白Word文档，新文件ID: {}", newFileId);
                    } else {
                        log.error("上传空白Word文档失败: {}", uploadResult.getMessage());
                    }
                }
            } catch (Exception e) {
                log.error("上传空白Word文档过程中发生异常，但不影响模版创建流程", e);
            }
        }
        
        // 判断是新增还是修改
        boolean isUpdate = dto.getTemplateId() != null;

        ContractTemplateEntity template;

        if (isUpdate) {
            // 修改模版
            template = updateTemplate(dto);
            log.info("修改合同模版，模版ID: {}", template.getTemplateId());
        } else {
            // 新增模版
            template = addTemplate(dto);
            log.info("新增合同模版，模版ID: {}", template.getTemplateId());
        }

        // 处理模版字段
        handleTemplateFields(template.getTemplateId(), dto.getCustomFields(), dto.getDefaultFields(), isUpdate);

        return template.getTemplateId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTemplate(Integer templateId) {
        // 1. 检查模版是否存在
        ContractTemplateEntity template = contractTemplateMapper.selectById(templateId);
        if (template == null) {
            throw new RuntimeException("模版不存在，模版ID: " + templateId);
        }

        // 2. 权限判定：检查当前操作人是否为模版创建人
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (currentUser == null) {
            throw new RuntimeException("用户未登录，无法删除模版");
        }
        
        // 检查是否为模版创建人（publisherId字段存储的是创建人ID）
        if (template.getPublisherId() == null || !template.getPublisherId().equals(currentUser.getId())) {
            throw new RuntimeException("只有模版创建人才能删除该模版");
        }

        // 3. 删除模版自定义字段
        contractTemplateFieldMapper.deleteByTemplateId(templateId);
        log.info("删除合同模版自定义字段，模版ID: {}", templateId);

        // 4. 删除模版默认字段详情
        templateDefaultFieldDetailMapper.deleteByTemplateId(templateId);
        log.info("删除合同模版默认字段详情，模版ID: {}", templateId);

        // 5. 删除模版
        contractTemplateMapper.deleteById(templateId);
        log.info("删除合同模版，模版ID: {}", templateId);
    }

    @Override
    public ContractTemplateRespDTO getTemplateDetail(Integer templateId) {
        // 1. 获取模版基本信息
        ContractTemplateEntity template = contractTemplateMapper.selectById(templateId);
        if (template == null) {
            throw new RuntimeException("模版不存在，模版ID: " + templateId);
        }

        // 2. 租户权限验证已删除 - 允许访问所有模板详情

        // 3. 获取自定义字段列表
        List<ContractTemplateFieldEntity> customFields = contractTemplateFieldMapper.selectList(
                new LambdaQueryWrapper<ContractTemplateFieldEntity>()
                        .eq(ContractTemplateFieldEntity::getTemplateId, templateId)
                        .eq(ContractTemplateFieldEntity::getIsDefaultField, false)
                        .orderByAsc(ContractTemplateFieldEntity::getSortOrder)
        );

        // 4. 获取默认字段列表（通过工作流配置）
        List<ContractTemplateRespDTO.DefaultFieldRespDTO> defaultFieldDTOs = getDefaultFieldsByWorkflow(template);

        // 5. 构建返回对象
        ContractTemplateRespDTO respDTO = new ContractTemplateRespDTO();
        BeanUtils.copyProperties(template, respDTO);

        // 6. 处理文件信息
        if (template.getTemplateFileId() != null) {
            // 设置templateFileId
            respDTO.setTemplateFileId(template.getTemplateFileId());

            SingleResponse<FileVO> fileResult = fileInfoService.getFileInfoById(template.getTemplateFileId().toString());
            if (fileResult.isSuccess()) {
                FileVO fileInfo = fileResult.getData();
                respDTO.setFileInfo(fileInfo);
                // 设置templateFileUrl为fileKey
                respDTO.setTemplateFileUrl(fileInfo.getFileKey());
                // 设置templateFileName为文件名
                respDTO.setTemplateFileName(fileInfo.getFileName());
            }
        }

        // 7. 转换自定义字段列表（按排序返回）
        if (!CollectionUtils.isEmpty(customFields)) {
            List<ContractTemplateRespDTO.CustomFieldRespDTO> customFieldDTOs = customFields.stream()
                    .map(field -> {
                        ContractTemplateRespDTO.CustomFieldRespDTO fieldDTO =
                                new ContractTemplateRespDTO.CustomFieldRespDTO();
                        BeanUtils.copyProperties(field, fieldDTO);
                        return fieldDTO;
                    })
                    .collect(Collectors.toList());
            respDTO.setCustomFields(customFieldDTOs);
        } else {
            respDTO.setCustomFields(null);
        }

        // 8. 设置默认字段列表（已排序）
        respDTO.setDefaultFields(defaultFieldDTOs);

        // 9. 直接从模板的content字段获取表单数据
        try {
            if (template.getContent() != null && !template.getContent().trim().isEmpty()) {
                // 直接解析JSON字符串为ContractFormDataDTO，不做任何处理
                ContractFormDataDTO formDataDTO = JSON.parseObject(template.getContent(), ContractFormDataDTO.class);
                respDTO.setContent(formDataDTO);
            } else {
                respDTO.setContent(new ContractFormDataDTO()); // 如果content为空，返回空对象
            }
        } catch (Exception e) {
            log.warn("解析合同模版content失败，模版ID: {}", templateId, e);
            respDTO.setContent(new ContractFormDataDTO()); // 返回空对象
        }

        return respDTO;
    }

    /**
     * 构建模版表单数据对象
     *
     * @param schemaContent 模式内容
     * @return ContractFormDataDTO对象
     */
    private ContractFormDataDTO buildTemplateFormData(String schemaContent) {
        ContractFormDataDTO formDataDTO = new ContractFormDataDTO();
        
        // 设置schema（模版的content内容，直接使用字符串）
        formDataDTO.setSchema(schemaContent);
        
        // 模版阶段没有实际字段值，所以formData为空
        
        log.debug("构建模版表单数据成功，schema是否为空: {}", schemaContent == null);
        
        return formDataDTO;
    }

    /**
     * 根据工作流配置获取默认字段列表
     *
     * @param template 合同模版实体
     * @return 默认字段列表
     */
    private List<ContractTemplateRespDTO.DefaultFieldRespDTO> getDefaultFieldsByWorkflow(ContractTemplateEntity template) {
        try {
            // 1. 获取合同模版的最深层级合同类型ID
            Integer contractTypeId = getTemplateDeepestContractTypeId(template);
            if (contractTypeId == null) {
                log.info("合同模版没有设置合同类型，模版ID: {}", template.getTemplateId());
                return new ArrayList<>();
            }

            // 2. 根据合同类型ID在contract_workflow_type表查找workflowId，并选择优先级最高的
            List<ContractWorkflowTypeEntity> workflowTypes = contractWorkflowTypeService.list(
                    new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                            .eq(ContractWorkflowTypeEntity::getContractTypeId, contractTypeId)
            );

            if (CollectionUtils.isEmpty(workflowTypes)) {
                log.info("未找到合同类型对应的工作流，合同类型ID: {}", contractTypeId);
                return new ArrayList<>();
            }

            // 获取所有workflowId
            List<Long> workflowIds = workflowTypes.stream()
                    .map(ContractWorkflowTypeEntity::getWorkflowId)
                    .collect(Collectors.toList());

            // 查询所有对应的工作流，并选择优先级最高的（已发布的）
            List<ContractWorkflowEntity> workflows = contractWorkflowService.list(
                    new LambdaQueryWrapper<ContractWorkflowEntity>()
                            .in(ContractWorkflowEntity::getId, workflowIds)
                            .eq(ContractWorkflowEntity::getIsEnabled, true)
                            .orderByDesc(ContractWorkflowEntity::getPriority)
            );

            if (CollectionUtils.isEmpty(workflows)) {
                log.info("未找到已发布的工作流，合同类型ID: {}", contractTypeId);
                return new ArrayList<>();
            }

            // 选择优先级最高的工作流
            ContractWorkflowEntity selectedWorkflow = workflows.get(0);
            Long workflowId = selectedWorkflow.getId();

            // 3. 获取工作流的processId（已经在上一步查询到了）
            if (selectedWorkflow.getProcessKey() == null) {
                log.info("工作流没有关联流程，工作流ID: {}", workflowId);
                return new ArrayList<>();
            }

            String processKey = selectedWorkflow.getProcessKey();

            // 根据processKey查找process_version最高的流程记录
            FlwProcess flwProcess = flwProcessMapper.selectOne(
                    new LambdaQueryWrapper<FlwProcess>()
                            .eq(FlwProcess::getProcessKey, processKey)
                            .orderByDesc(FlwProcess::getProcessVersion)
                            .last("LIMIT 1")
            );
            
            if (flwProcess == null) {
                log.info("未找到流程，流程key: {}", processKey);
                return new ArrayList<>();
            }
            
            Long processId = flwProcess.getId();
            log.info("找到流程，流程key: {}, 版本: {}, processId: {}", processKey, flwProcess.getProcessVersion(), processId);

            // 4. 根据processId在flw_process_configure表查找process_form字段
            // 注意：这里的processId是flw_process表的主键，在flw_process_configure表中作为processId字段存储
            FlwProcessConfigure processConfigure = flwProcessConfigureService.getByProcessId(processId);
            if (processConfigure == null || processConfigure.getProcessForm() == null) {
                log.info("未找到流程配置或流程表单配置，流程processId: {}", processId);
                return new ArrayList<>();
            }

            // 5. 解析process_form JSON，获取formId
            String processForm = processConfigure.getProcessForm();
            String formId = null;
            try {
                Map<String, Object> formMap = JSON.parseObject(processForm, Map.class);
                if (formMap != null && formMap.containsKey("formId")) {
                    formId = (String) formMap.get("formId");
                }
            } catch (Exception e) {
                log.warn("解析process_form JSON失败，processId: {}, processForm: {}", processId, processForm, e);
            }

            if (formId == null) {
                log.info("未能从process_form中解析出formId，流程ID: {}", processId);
                return new ArrayList<>();
            }

            Long formIdLong;
            try {
                formIdLong = Long.parseLong(formId);
            } catch (NumberFormatException e) {
                log.warn("formId格式错误，无法转换为Long，formId: {}", formId);
                return new ArrayList<>();
            }

            // 6. 根据解析出的formId作为workflowId，在contract_workflow_form_field表中查询对应的field_id列表
            List<ContractWorkflowFormFieldEntity> workflowFormFields = contractWorkflowFormFieldService.list(
                    new LambdaQueryWrapper<ContractWorkflowFormFieldEntity>()
                            .eq(ContractWorkflowFormFieldEntity::getWorkflowId, formIdLong)
                            .eq(ContractWorkflowFormFieldEntity::getIsHidden, false)
                            .eq(ContractWorkflowFormFieldEntity::getIsEnabled, true)
                            .eq(ContractWorkflowFormFieldEntity::getIsDeleted, false)
                            .orderByAsc(ContractWorkflowFormFieldEntity::getFieldOrder)
            );

            if (CollectionUtils.isEmpty(workflowFormFields)) {
                log.info("未找到表单字段配置，formId作为workflowId: {}", formIdLong);
                return new ArrayList<>();
            }

            // 7. 获取所有字段ID
            List<Long> fieldIds = workflowFormFields.stream()
                    .map(ContractWorkflowFormFieldEntity::getFieldId)
                    .collect(Collectors.toList());

            // 8. 批量获取字段基本信息
            Map<Long, ContractFieldEntity> fieldMap = new HashMap<>();
            if (!fieldIds.isEmpty()) {
                List<ContractFieldEntity> contractFields = contractFieldService.listByIds(fieldIds);
                fieldMap = contractFields.stream()
                        .collect(Collectors.toMap(ContractFieldEntity::getId, field -> field));
            }

            // 9. 根据template_id和字段ID查询模版默认字段详情配置
            Map<Long, TemplateDefaultFieldDetailEntity> templateFieldDetailMap = new HashMap<>();
            if (!fieldIds.isEmpty()) {
                List<TemplateDefaultFieldDetailEntity> templateFieldDetails = templateDefaultFieldDetailMapper.selectList(
                        new LambdaQueryWrapper<TemplateDefaultFieldDetailEntity>()
                                .eq(TemplateDefaultFieldDetailEntity::getTemplateId, template.getTemplateId())
                                .in(TemplateDefaultFieldDetailEntity::getFieldId, fieldIds)
                );
                templateFieldDetailMap = templateFieldDetails.stream()
                        .collect(Collectors.toMap(TemplateDefaultFieldDetailEntity::getFieldId, detail -> detail));
            }

            // 10. 构建默认字段DTO列表
            List<ContractTemplateRespDTO.DefaultFieldRespDTO> defaultFieldDTOs = new ArrayList<>();
            final Map<Long, ContractFieldEntity> finalFieldMap = fieldMap;
            final Map<Long, TemplateDefaultFieldDetailEntity> finalTemplateFieldDetailMap = templateFieldDetailMap;

            for (ContractWorkflowFormFieldEntity workflowField : workflowFormFields) {
                ContractFieldEntity contractField = finalFieldMap.get(workflowField.getFieldId());
                if (contractField == null) {
                    log.warn("未找到字段信息，字段ID: {}", workflowField.getFieldId());
                    continue;
                }

                ContractTemplateRespDTO.DefaultFieldRespDTO fieldDTO =
                        new ContractTemplateRespDTO.DefaultFieldRespDTO();

                // 设置字段基本信息
                fieldDTO.setFieldId(contractField.getId());
                fieldDTO.setFieldName(contractField.getFieldName());
                fieldDTO.setFieldType(contractField.getFieldType());
                fieldDTO.setFieldDescription(contractField.getFieldDescription());

                // 设置工作流字段信息（是否必填等）
                fieldDTO.setIsRequired(workflowField.getIsRequired());

                // 获取模版中对该字段的具体配置
                TemplateDefaultFieldDetailEntity templateDetail = finalTemplateFieldDetailMap.get(workflowField.getFieldId());
                if (templateDetail != null) {
                    // 使用模版中的配置
                    fieldDTO.setId(templateDetail.getId());
                    fieldDTO.setUsageCount(templateDetail.getUsageCount());
                    fieldDTO.setSortOrder(templateDetail.getSortOrder());
                    fieldDTO.setSupportDefaultValue(templateDetail.getSupportDefaultValue());
                    fieldDTO.setDefaultValue(templateDetail.getDefaultValue());
                    fieldDTO.setSupportCounterpartyInput(templateDetail.getSupportCounterpartyInput());
                } else {
                    // 使用默认配置
                    fieldDTO.setId(null);
                    fieldDTO.setUsageCount(0);
                    fieldDTO.setSortOrder(workflowField.getFieldOrder()); // 使用工作流中的排序
                    fieldDTO.setSupportDefaultValue(false);
                    fieldDTO.setDefaultValue(null);
                    fieldDTO.setSupportCounterpartyInput(false);
                }

                defaultFieldDTOs.add(fieldDTO);
            }

            // 11. 按排序字段排序（优先使用template_default_field_detail表中的sort_order，否则使用工作流字段的field_order）
            defaultFieldDTOs.sort((f1, f2) -> {
                Integer order1 = f1.getSortOrder() != null ? f1.getSortOrder() : 999;
                Integer order2 = f2.getSortOrder() != null ? f2.getSortOrder() : 999;
                return order1.compareTo(order2);
            });

            return defaultFieldDTOs;

        } catch (Exception e) {
            log.error("获取默认字段列表失败，模版ID: {}", template.getTemplateId(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 生成模版编号
     * 格式：年月日+序号，如：202506300001
     *
     * @return 生成的模版编号
     */
    private String generateTemplateCode() {
        // 获取当前日期，格式为yyyyMMdd
        String dateStr = LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 查询今天已创建的模版数量
        LambdaQueryWrapper<ContractTemplateEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(ContractTemplateEntity::getTemplateCode, dateStr)
                .isNotNull(ContractTemplateEntity::getTemplateCode);

        Long todayCount = contractTemplateMapper.selectCount(queryWrapper);

        // 下一个序号（从1开始）
        int nextNumber = todayCount.intValue() + 1;

        // 格式化为4位数字
        String numberStr = String.format("%04d", nextNumber);

        return dateStr + numberStr;
    }

    /**
     * 新增模版
     */
    private ContractTemplateEntity addTemplate(ContractTemplateAddReqDTO dto) {
        ContractTemplateEntity template = new ContractTemplateEntity();
        BeanUtils.copyProperties(dto, template);
        template.setCreatedAt(LocalDateTime.now());
        template.setUpdatedAt(LocalDateTime.now());

        // 生成模版编号
        template.setTemplateCode(generateTemplateCode());

        // 确保status有默认值
        if (template.getStatus() == null || template.getStatus().trim().isEmpty()) {
            template.setStatus("draft");
        }

        // if ("published".equals(dto.getStatus())) {
        template.setPublisherId(dto.getPublisherId());
        // }

        // 从AuthUtil获取当前用户的租户键
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (currentUser != null) {
            String sysTenantKey = null;

            // 优先从sysTenantKey字段获取
            if (currentUser.getSysTenantKey() != null) {
                sysTenantKey = currentUser.getSysTenantKey();
            }
            // 如果sysTenantKey为空，且是LoginUserVo类型，从sysTenantList获取第一个
            else if (currentUser instanceof com.aizuda.boot.modules.system.entity.vo.LoginUserVo) {
                com.aizuda.boot.modules.system.entity.vo.LoginUserVo loginUserVo =
                    (com.aizuda.boot.modules.system.entity.vo.LoginUserVo) currentUser;
                if (loginUserVo.getSysTenantList() != null && !loginUserVo.getSysTenantList().isEmpty()) {
                    sysTenantKey = loginUserVo.getSysTenantList().get(0).getTenantKey();
                }
            }

            if (sysTenantKey != null) {
                template.setSysTenantKey(sysTenantKey);
                log.info("设置模板租户键: {}", sysTenantKey);
            } else {
                log.warn("无法获取当前用户的租户键，模板将不设置sysTenantKey");
            }
        }

        // 匹配并设置content
        String content = matchAndSetContent(template);
        template.setContent(content);

        contractTemplateMapper.insert(template);

        // 保存模板后，更新processKey
        updateTemplateProcessKey(template);

        return template;
    }

    /**
     * 匹配并设置模板content
     */
    private String matchAndSetContent(ContractTemplateEntity template) {
        try {
            // 获取模板的最深层级合同类型ID
            Integer contractTypeId = getTemplateDeepestContractTypeId(template);
            if (contractTypeId == null) {
                throw new RuntimeException("当前合同类型未配置审批流程，请联系管理员配置");
            }

            // 获取当前用户的主部门ID
            UserInfo currentUser = AuthUtil.getCurrentUser();
            Long userDepartmentId = null;
            if (currentUser != null) {
                userDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
            }

            // 匹配content - 直接获取字符串
            ContractFormDataDTO formDataDTO = getContentByContractTypeAndDepartment(contractTypeId, userDepartmentId);
            if (formDataDTO == null) {
                throw new RuntimeException("当前合同类型未配置审批流程，请联系管理员配置");
            }

            // 直接返回JSON字符串，不做任何处理
            return JSON.toJSONString(formDataDTO);

        } catch (Exception e) {
            log.error("匹配模板content失败", e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 修改模版
     */
    private ContractTemplateEntity updateTemplate(ContractTemplateAddReqDTO dto) {
        ContractTemplateEntity template = contractTemplateMapper.selectById(dto.getTemplateId());
        if (template == null) {
            throw new RuntimeException("模版不存在，模版ID: " + dto.getTemplateId());
        }

        // 更新模版基本信息
        BeanUtils.copyProperties(dto, template);
        template.setUpdatedAt(LocalDateTime.now());

        // 确保status有默认值
        if (template.getStatus() == null || template.getStatus().trim().isEmpty()) {
            template.setStatus("draft");
        }

        // 如果是发布状态，设置发布者ID
        // if ("published".equals(dto.getStatus())) {
        template.setPublisherId(dto.getPublisherId());
        // }

        // 重新匹配并设置content（因为合同类型可能发生变化）
        String content = matchAndSetContent(template);
        template.setContent(content);

        contractTemplateMapper.updateById(template);

        // 更新模板后，只在processKey为空时设置processKey（不覆盖已有的processKey）
        updateTemplateProcessKey(template);

        return template;
    }

    /**
     * 更新模板的processKey（只在processKey为空时设置）
     */
    private void updateTemplateProcessKey(ContractTemplateEntity template) {
        try {
            // 检查模板是否已经有processKey，如果有则不再修改
            if (template.getProcessKey() != null) {
                log.info("模板已有processKey，不再修改，模板ID: {}, processKey: {}", template.getTemplateId(), template.getProcessKey());
                return;
            }

            // 获取模板的最深层级合同类型ID
            Integer contractTypeId = getTemplateDeepestContractTypeId(template);
            if (contractTypeId == null) {
                log.warn("模板没有设置合同类型，无法获取processKey，模板ID: {}", template.getTemplateId());
                return;
            }

            // 获取当前用户的主部门ID
            UserInfo currentUser = AuthUtil.getCurrentUser();
            Long userDepartmentId = null;
            if (currentUser != null) {
                userDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
            }

            if (userDepartmentId == null) {
                log.warn("无法获取用户部门信息，无法获取processKey，模板ID: {}", template.getTemplateId());
                return;
            }

            // 调用获取content的方法，并传入templateId以保存processKey
            getContentByContractTypeAndDepartment(contractTypeId, userDepartmentId, template.getTemplateId());

        } catch (Exception e) {
            log.error("更新模板processKey失败，模板ID: {}", template.getTemplateId(), e);
        }
    }

    @Override
    public void updateTemplateContentByProcessKey(String processKey) {
        try {
            log.info("开始根据processKey更新模板content，processKey: {}", processKey);

            // 1. 查找所有使用该processKey的模板
            List<ContractTemplateEntity> templates = contractTemplateMapper.selectList(
                    new LambdaQueryWrapper<ContractTemplateEntity>()
                            .eq(ContractTemplateEntity::getProcessKey, processKey)
            );

            if (CollectionUtils.isEmpty(templates)) {
                log.info("未找到使用processKey的模板，processKey: {}", processKey);
                return;
            }

            log.info("找到{}个使用processKey的模板，processKey: {}", templates.size(), processKey);

            // 2. 根据processKey获取最新的表单内容
            String newContent = getContentByProcessKey(processKey);
            if (newContent == null) {
                log.warn("无法获取processKey对应的表单内容，processKey: {}", processKey);
                return;
            }

            // 3. 批量更新模板的content
            int updatedCount = 0;
            for (ContractTemplateEntity template : templates) {
                try {
                    template.setContent(newContent);
                    template.setUpdatedAt(LocalDateTime.now());
                    contractTemplateMapper.updateById(template);
                    updatedCount++;
                    log.info("成功更新模板content，模板ID: {}, 模板名称: {}", template.getTemplateId(), template.getTemplateName());
                } catch (Exception e) {
                    log.error("更新模板content失败，模板ID: {}, 模板名称: {}", template.getTemplateId(), template.getTemplateName(), e);
                }
            }

            log.info("批量更新模板content完成，processKey: {}, 总数: {}, 成功: {}", processKey, templates.size(), updatedCount);

        } catch (Exception e) {
            log.error("根据processKey更新模板content失败，processKey: {}", processKey, e);
        }
    }

    @Override
    public void updateTemplateContentByProcessId(Long processId) {
        try {
            log.info("开始根据processId更新模板content，processId: {}", processId);

            // 1. 根据processId查询对应的processKey
            FlwProcess flwProcess = flwProcessMapper.selectById(processId);
            if (flwProcess == null) {
                log.warn("未找到流程，processId: {}", processId);
                return;
            }

            String processKey = flwProcess.getProcessKey();
            if (processKey == null) {
                log.warn("流程的processKey为空，processId: {}", processId);
                return;
            }

            log.info("找到流程processKey: {}，processId: {}", processKey, processId);

            // 2. 根据processId获取最新的表单内容
            String newContent = getContentByProcessIdDirect(processId);
            if (newContent == null) {
                log.warn("无法获取processId对应的表单内容，processId: {}", processId);
                return;
            }

            // 3. 查找所有使用该processKey的模板
            List<ContractTemplateEntity> templates = contractTemplateMapper.selectList(
                    new LambdaQueryWrapper<ContractTemplateEntity>()
                            .eq(ContractTemplateEntity::getProcessKey, processKey)
            );

            if (CollectionUtils.isEmpty(templates)) {
                log.info("未找到使用processKey的模板，processKey: {}", processKey);
                return;
            }

            log.info("找到{}个使用processKey的模板，processKey: {}", templates.size(), processKey);

            // 4. 批量更新模板的content
            int updatedCount = 0;
            for (ContractTemplateEntity template : templates) {
                try {
                    template.setContent(newContent);
                    template.setUpdatedAt(LocalDateTime.now());
                    contractTemplateMapper.updateById(template);
                    updatedCount++;
                    log.info("成功更新模板content，模板ID: {}, 模板名称: {}", template.getTemplateId(), template.getTemplateName());
                } catch (Exception e) {
                    log.error("更新模板content失败，模板ID: {}, 模板名称: {}", template.getTemplateId(), template.getTemplateName(), e);
                }
            }

            log.info("批量更新模板content完成，processKey: {}, processId: {}, 总数: {}, 成功: {}", processKey, processId, templates.size(), updatedCount);

        } catch (Exception e) {
            log.error("根据processId更新模板content失败，processId: {}", processId, e);
        }
    }

    /**
     * 直接根据processId获取表单内容（不通过processKey查找）
     */
    private String getContentByProcessIdDirect(Long processId) {
        Long originalProcessId = processId;
        try {
            // 1. 根据processId在flw_process_configure表查找process_form字段
            FlwProcessConfigure processConfigure = flwProcessConfigureService.getByProcessId(processId);
            if (processConfigure == null || processConfigure.getProcessForm() == null) {
                log.info("未找到流程配置或流程表单配置，流程processId: {}", processId);
                return null;
            }

            // 2. 解析process_form JSON，提取formId
            String processForm = processConfigure.getProcessForm();
            String formId = null;
            try {
                Map<String, Object> formMap = JSON.parseObject(processForm, Map.class);
                if (formMap != null && formMap.containsKey("formId")) {
                    formId = (String) formMap.get("formId");
                }
            } catch (Exception e) {
                log.warn("解析process_form JSON失败，processId: {}, processForm: {}", processId, processForm, e);
                return null;
            }

            if (formId == null) {
                log.info("未能从process_form中解析出formId，流程ID: {}", processId);
                return null;
            }

            Long formIdLong;
            try {
                formIdLong = Long.parseLong(formId);
            } catch (NumberFormatException e) {
                log.warn("formId格式错误，无法转换为Long，formId: {}", formId);
                return null;
            }

            // 3. 根据解析出的formId在flw_form_template表中查询content
            FlwFormTemplate formTemplate = flwFormTemplateService.getById(formIdLong);
            if (formTemplate == null) {
                log.info("未找到表单模版，formId: {}", formIdLong);
                return null;
            }

            String schemaContent = formTemplate.getContent();
            if (schemaContent == null) {
                log.warn("表单模版content为空，formId: {}", formIdLong);
                return null;
            }

            // 4. 构建ContractFormDataDTO对象并转换为JSON字符串
            ContractFormDataDTO formDataDTO = buildTemplateFormData(schemaContent);
            return JSON.toJSONString(formDataDTO);

        } catch (Exception e) {
            log.error("根据processId获取表单内容失败，processId: {}", originalProcessId, e);
            return null;
        }
    }

    /**
     * 根据processKey获取表单内容
     */
    private String getContentByProcessKey(String processKey) {
        Long processId = null;
        try {
            // 1. 根据processKey查找最新版本的流程
            FlwProcess flwProcess = flwProcessMapper.selectOne(
                    new LambdaQueryWrapper<FlwProcess>()
                            .eq(FlwProcess::getProcessKey, processKey)
                            .orderByDesc(FlwProcess::getProcessVersion)
                            .last("LIMIT 1")
            );

            if (flwProcess == null) {
                log.info("未找到流程，流程key: {}", processKey);
                return null;
            }

            processId = flwProcess.getId();

            // 2. 根据processId在flw_process_configure表查找process_form字段
            FlwProcessConfigure processConfigure = flwProcessConfigureService.getByProcessId(processId);
            if (processConfigure == null || processConfigure.getProcessForm() == null) {
                log.info("未找到流程配置或流程表单配置，流程processKey: {}, processId: {}", processKey, processId);
                return null;
            }

            // 3. 解析process_form JSON，获取formId
            String processForm = processConfigure.getProcessForm();
            String formId = null;
            try {
                Map<String, Object> formMap = JSON.parseObject(processForm, Map.class);
                if (formMap != null && formMap.containsKey("formId")) {
                    formId = (String) formMap.get("formId");
                }
            } catch (Exception e) {
                log.warn("解析process_form JSON失败，processKey: {}, processId: {}, processForm: {}", processKey, processId, processForm, e);
                return null;
            }

            if (formId == null) {
                log.info("未能从process_form中解析出formId，流程Key: {}, 流程ID: {}", processKey, processId);
                return null;
            }

            Long formIdLong;
            try {
                formIdLong = Long.parseLong(formId);
            } catch (NumberFormatException e) {
                log.warn("formId格式错误，无法转换为Long，formId: {}", formId);
                return null;
            }

            // 4. 根据解析出的formId在flw_form_template表中查询content
            FlwFormTemplate formTemplate = flwFormTemplateService.getById(formIdLong);
            if (formTemplate == null) {
                log.info("未找到表单模版，formId: {}", formIdLong);
                return null;
            }

            String schemaContent = formTemplate.getContent();
            if (schemaContent == null) {
                log.warn("表单模版content为空，formId: {}", formIdLong);
                return null;
            }

            // 5. 构建ContractFormDataDTO对象并转换为JSON字符串
            ContractFormDataDTO formDataDTO = buildTemplateFormData(schemaContent);
            return JSON.toJSONString(formDataDTO);

        } catch (Exception e) {
            log.error("根据processKey获取表单内容失败，processKey: {}, processId: {}", processKey, processId, e);
            return null;
        }
    }

    /**
     * 处理模版字段
     */
    private void handleTemplateFields(Integer templateId,
                                      List<ContractTemplateAddReqDTO.CustomFieldReqDTO> customFields,
                                      List<ContractTemplateAddReqDTO.DefaultFieldReqDTO> defaultFields,
                                      boolean isUpdate) {
        if (isUpdate) {
            // 修改时先删除原有的自定义字段和默认字段
            contractTemplateFieldMapper.deleteByTemplateId(templateId);
            templateDefaultFieldDetailMapper.deleteByTemplateId(templateId);
        }

        // 处理自定义字段
        handleCustomFields(templateId, customFields, isUpdate);

        // 处理默认字段
        handleDefaultFields(templateId, defaultFields);
    }

    /**
     * 处理自定义字段
     */
    private void handleCustomFields(Integer templateId,
                                    List<ContractTemplateAddReqDTO.CustomFieldReqDTO> customFields,
                                    boolean isUpdate) {
        if (CollectionUtils.isEmpty(customFields)) {
            return;
        }

        // 构建自定义字段实体列表
        List<ContractTemplateFieldEntity> fields = new ArrayList<>();
        int fieldIndex = 1; // 每个模版的字段编码从1开始

        for (ContractTemplateAddReqDTO.CustomFieldReqDTO fieldDTO : customFields) {
            ContractTemplateFieldEntity field = new ContractTemplateFieldEntity();
            BeanUtils.copyProperties(fieldDTO, field);

            // 生成雪花算法ID
            field.setId(IdWorker.getId());

            field.setTemplateId(templateId);
            field.setIsDefaultField(false); // 自定义字段
            field.setCreatedAt(new Timestamp(System.currentTimeMillis()));
            field.setUpdatedAt(new Timestamp(System.currentTimeMillis()));

            // 为每个模版独立生成字段编码：ext1, ext2, ext3...
            field.setFieldCode("ext" + fieldIndex);
            fieldIndex++;

            // 设置默认值
            if (field.getIsRequired() == null) {
                field.setIsRequired(false);
            }
            if (field.getAllowCounterpartyFill() == null) {
                field.setAllowCounterpartyFill(false);
            }
            if (field.getUsageCount() == null) {
                field.setUsageCount(0);
            }

            fields.add(field);
        }

        // 批量插入自定义字段
        if (!fields.isEmpty()) {
            contractTemplateFieldMapper.batchInsert(fields);
        }
    }

    /**
     * 处理默认字段
     */
    private void handleDefaultFields(Integer templateId,
                                     List<ContractTemplateAddReqDTO.DefaultFieldReqDTO> defaultFields) {
        if (CollectionUtils.isEmpty(defaultFields)) {
            return;
        }

        // 构建默认字段详情实体列表
        List<TemplateDefaultFieldDetailEntity> fieldDetails = new ArrayList<>();
        for (ContractTemplateAddReqDTO.DefaultFieldReqDTO fieldDTO : defaultFields) {
            TemplateDefaultFieldDetailEntity fieldDetail = new TemplateDefaultFieldDetailEntity();
            fieldDetail.setTemplateId(templateId);
            fieldDetail.setFieldId(fieldDTO.getFieldId());
            fieldDetail.setSortOrder(fieldDTO.getSortOrder());
            fieldDetail.setSupportDefaultValue(fieldDTO.getSupportDefaultValue());
            fieldDetail.setDefaultValue(fieldDTO.getDefaultValue());
            fieldDetail.setSupportCounterpartyInput(fieldDTO.getSupportCounterpartyInput());
            fieldDetail.setCreatedAt(new Timestamp(System.currentTimeMillis()));
            fieldDetail.setUpdatedAt(new Timestamp(System.currentTimeMillis()));

            // 设置默认值
            if (fieldDetail.getUsageCount() == null) {
                fieldDetail.setUsageCount(0);
            }
            if (fieldDetail.getSupportDefaultValue() == null) {
                fieldDetail.setSupportDefaultValue(false);
            }
            if (fieldDetail.getSupportCounterpartyInput() == null) {
                fieldDetail.setSupportCounterpartyInput(false);
            }

            fieldDetails.add(fieldDetail);
        }

        // 批量插入默认字段详情
        if (!fieldDetails.isEmpty()) {
            templateDefaultFieldDetailMapper.batchInsert(fieldDetails);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recordTemplateUsage(Long userId, Integer templateId) {
        // 1. 检查模版是否存在
        ContractTemplateEntity template = contractTemplateMapper.selectById(templateId);
        if (template == null) {
            throw new RuntimeException("模版不存在，模版ID: " + templateId);
        }

        // 2. 查询是否已有使用记录
        ContractTemplateUsageEntity usage = contractTemplateUsageMapper.selectOne(
                new LambdaQueryWrapper<ContractTemplateUsageEntity>()
                        .eq(ContractTemplateUsageEntity::getEmployeeId, userId)
                        .eq(ContractTemplateUsageEntity::getTemplateId, templateId)
        );

        LocalDateTime now = LocalDateTime.now();

        if (usage == null) {
            // 3. 新增使用记录
            usage = new ContractTemplateUsageEntity();
            usage.setEmployeeId(userId);
            usage.setTemplateId(templateId);
            usage.setUsedAt(now);
            usage.setCreatedAt(now);
            contractTemplateUsageMapper.insert(usage);
        } else {
            // 4. 更新使用时间
            usage.setUsedAt(now);
            contractTemplateUsageMapper.updateById(usage);
        }
    }

    @Override
    public List<Map<String, Object>> getRecentTemplates(Long employeeId, Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10; // 默认返回10条
        }

        // 获取当前用户租户键 - 修改逻辑：优先使用当前租户，如果为空则使用租户列表
        UserInfo currentUser = AuthUtil.getCurrentUser();
        String currentSysTenantKey = currentUser != null ? currentUser.getSysTenantKey() : null;
        List<String> userTenantKeys = null;

        if (currentSysTenantKey == null || currentSysTenantKey.trim().isEmpty()) {
            // 如果sysTenantKey为null或空，获取用户有权限的所有租户
            userTenantKeys = AuthUtil.getUserTenantKeys();
        }

        // 获取当前用户权限过滤条件（部门权限 + 用户权限的并集）
        if (currentUser == null || currentUser.getId() == null) {
            log.warn("无法获取当前用户信息，返回空的模板列表");
            return new ArrayList<>();
        }

        // 获取允许的合同类型ID集合（部门权限 + 用户权限的并集）
        Set<Integer> allowedTypeIds = new HashSet<>();
        
        // 1. 按部门授权：查询当前用户主部门可用的合同类型ID列表
        Long mainDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
        if (mainDepartmentId != null) {
            List<ContractTypeDepartmentEntity> typeDepartments = contractTypeDepartmentService.list(
                    new LambdaQueryWrapper<ContractTypeDepartmentEntity>()
                            .eq(ContractTypeDepartmentEntity::getDepartmentId, mainDepartmentId)
            );
            allowedTypeIds.addAll(typeDepartments.stream()
                    .map(ContractTypeDepartmentEntity::getContractTypeId)
                    .collect(Collectors.toSet()));
        }
        
        // 2. 按人员授权：查询当前用户可用的合同类型ID列表
        List<ContractTypeUser> typeUsersForCurrent = contractTypeUserService.list(
                new LambdaQueryWrapper<ContractTypeUser>()
                        .eq(ContractTypeUser::getUserId, currentUser.getId())
        );
        allowedTypeIds.addAll(typeUsersForCurrent.stream()
                .map(ContractTypeUser::getContractTypeId)
                .collect(Collectors.toSet()));
        
        if (allowedTypeIds.isEmpty()) {
            log.debug("用户 {} 没有任何合同类型权限（部门权限和用户权限都为空）", currentUser.getId());
            return new ArrayList<>();
        }

        List<Map<String, Object>> templates = contractTemplateUsageMapper.selectRecentTemplates(employeeId, limit, currentSysTenantKey, userTenantKeys);

        // 根据部门权限过滤模板
        templates = templates.stream()
                .filter(template -> {
                    Object contractTypeIdObj = template.get("contract_type_id");
                    if (contractTypeIdObj == null) {
                        return false; // 没有合同类型的模板不显示
                    }
                    Integer contractTypeId = Integer.valueOf(contractTypeIdObj.toString());
                    return allowedTypeIds.contains(contractTypeId);
                })
                .collect(Collectors.toList());

        log.debug("部门 {} 过滤前模板数量: {}, 过滤后数量: {}", mainDepartmentId,
                contractTemplateUsageMapper.selectRecentTemplates(employeeId, limit, currentSysTenantKey, userTenantKeys).size(),
                templates.size());

        // 收集所有发布者ID和文件ID
        Set<Long> publisherIds = new HashSet<>();
        Set<Integer> fileIds = new HashSet<>();
        
        for (Map<String, Object> template : templates) {
            Object publisherIdObj = template.get("publisher_id");
            if (publisherIdObj != null) {
                publisherIds.add(Long.valueOf(publisherIdObj.toString()));
            }
            
            Object fileIdObj = template.get("template_file_id");
            if (fileIdObj != null) {
                fileIds.add(Integer.valueOf(fileIdObj.toString()));
            }
        }

        // 批量获取发布者信息
        Map<Long, LoginCheckVO> publisherInfoMap = new HashMap<>();
        if (!publisherIds.isEmpty()) {
            try {
                publisherInfoMap = batchGetPublisherInfo(publisherIds);
            } catch (Exception e) {
                log.warn("批量获取发布者信息失败", e);
            }
        }

        // 批量获取文件信息
        Map<Integer, FileVO> fileInfoMap = new HashMap<>();
        if (!fileIds.isEmpty()) {
            try {
                fileInfoMap = batchGetFileInfo(fileIds);
            } catch (Exception e) {
                log.warn("批量获取文件信息失败", e);
            }
        }

        // 处理合同类型名称，将逗号分隔的字符串转换为数组，并添加content字段和其他扩展字段
        for (Map<String, Object> template : templates) {
            // 处理合同类型名称
            String typeNames = (String) template.get("contract_type_names");
            if (typeNames != null) {
                template.put("contract_type_names", typeNames.split(","));
            }
            
            // 处理发布者信息
            Object publisherIdObj = template.get("publisher_id");
            if (publisherIdObj != null) {
                Long publisherId = Long.valueOf(publisherIdObj.toString());
                LoginCheckVO publisherInfo = publisherInfoMap.get(publisherId);
                if (publisherInfo != null) {
                    template.put("publisherName", publisherInfo.getName());
                    template.put("publisherAliasName", publisherInfo.getAliasName());
                    template.put("publisherAvatar", publisherInfo.getAvatar());
                } else {
                    template.put("publisherName", "");
                    template.put("publisherAliasName", "");
                    template.put("publisherAvatar", "");
                }
            } else {
                template.put("publisherName", "");
                template.put("publisherAliasName", "");
                template.put("publisherAvatar", "");
            }
            
            // 处理文件信息
            Object fileIdObj = template.get("template_file_id");
            if (fileIdObj != null) {
                Integer fileId = Integer.valueOf(fileIdObj.toString());
                FileVO fileInfo = fileInfoMap.get(fileId);
                if (fileInfo != null) {
                    template.put("fileInfo", fileInfo);
                    template.put("templateFileUrl", fileInfo.getFileKey());
                    template.put("templateFileName", fileInfo.getFileName());
                } else {
                    template.put("fileInfo", null);
                    template.put("templateFileUrl", "");
                    template.put("templateFileName", "");
                }
            } else {
                template.put("fileInfo", null);
                template.put("templateFileUrl", "");
                template.put("templateFileName", "");
            }
            
            // 添加content字段
            Object templateIdObj = template.get("template_id");
            if (templateIdObj != null) {
                try {
                    Integer templateId = (Integer) templateIdObj;
                    // 查询模版实体
                    ContractTemplateEntity templateEntity = contractTemplateMapper.selectById(templateId);
                    if (templateEntity != null) {
                        // 直接从模板的content字段获取表单数据
                        try {
                            if (templateEntity.getContent() != null && !templateEntity.getContent().trim().isEmpty()) {
                                // 直接解析JSON字符串，不做任何处理
                                ContractFormDataDTO formDataDTO = JSON.parseObject(templateEntity.getContent(), ContractFormDataDTO.class);
                                template.put("content", formDataDTO);
                            } else {
                                template.put("content", new ContractFormDataDTO()); // 如果content为空，返回空对象
                            }
                        } catch (Exception e) {
                            log.warn("解析最近使用模版content失败，模版ID: {}", templateId, e);
                            template.put("content", new ContractFormDataDTO()); // 返回空对象
                        }
                    } else {
                        template.put("content", new ContractFormDataDTO()); // 模版不存在时返回空对象
                    }
                } catch (Exception e) {
                    log.warn("处理最近使用模版的templateId失败: {}", templateIdObj, e);
                    template.put("content", new ContractFormDataDTO()); // 异常时返回空对象
                }
            } else {
                template.put("content", new ContractFormDataDTO()); // templateId为null时返回空对象
            }
        }

        // 针对指定字段，增加驼峰命名字段，原有下划线字段保留
        String[][] fieldPairs = {
            {"template_id", "templateId"},
            {"usage_instructions", "usageInstructions"},
            {"publisher_id", "publisherId"},
            {"contract_type_id", "contractTypeId"},
            {"template_code", "templateCode"},
            {"template_name", "templateName"},
            {"template_file_id", "templateFileId"}
        };
        for (Map<String, Object> template : templates) {
            for (String[] pair : fieldPairs) {
                Object value = template.get(pair[0]);
                if (value != null) {
                    template.put(pair[1], value);
                }
            }
        }

        return templates;
    }

    @Override
    public ContractTemplateDraftListRespDTO getTemplateDraftList(Long employeeId) {
        // 1. 查询该用户的所有草稿模板
        LambdaQueryWrapper<ContractTemplateEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ContractTemplateEntity::getPublisherId, employeeId)
                .eq(ContractTemplateEntity::getStatus, "draft")
                .orderByDesc(ContractTemplateEntity::getUpdatedAt);

        // 添加租户隔离条件 - 修改逻辑：优先使用当前租户，如果为空则使用租户列表
        UserInfo currentUser = AuthUtil.getCurrentUser();
        String currentSysTenantKey = currentUser != null ? currentUser.getSysTenantKey() : null;

        if (currentSysTenantKey != null && !currentSysTenantKey.trim().isEmpty()) {
            // 如果当前用户有明确的sysTenantKey，只查询该租户下的数据
            queryWrapper.eq(ContractTemplateEntity::getSysTenantKey, currentSysTenantKey);
        } else {
            // 如果sysTenantKey为null或空，使用原有逻辑（查询用户有权限的所有租户）
            List<String> userTenantKeys = AuthUtil.getUserTenantKeys();
            if (userTenantKeys != null && !userTenantKeys.isEmpty()) {
                queryWrapper.in(ContractTemplateEntity::getSysTenantKey, userTenantKeys);
            } else if (userTenantKeys != null) {
                // 空列表表示没有任何租户权限
                queryWrapper.eq(ContractTemplateEntity::getSysTenantKey, "NO_PERMISSION");
            }
        }

        List<ContractTemplateEntity> draftTemplates = contractTemplateMapper.selectList(queryWrapper);

        if (CollectionUtils.isEmpty(draftTemplates)) {
            return new ContractTemplateDraftListRespDTO();
        }

        // 2. 获取所有涉及的合同类型ID
        Set<Integer> contractTypeIds = new HashSet<>();
        draftTemplates.forEach(template -> {
            if (template.getContractTypeLevel1() != null) {
                contractTypeIds.add(template.getContractTypeLevel1());
            }
            if (template.getContractTypeLevel2() != null) {
                contractTypeIds.add(template.getContractTypeLevel2());
            }
            if (template.getContractTypeLevel3() != null) {
                contractTypeIds.add(template.getContractTypeLevel3());
            }
        });

        // 3. 查询所有相关的合同类型信息
        List<ContractTypeEntity> contractTypes = new ArrayList<>();
        if (!contractTypeIds.isEmpty()) {
            contractTypes = contractTypeMapper.selectBatchIds(contractTypeIds);
        }
        Map<Integer, ContractTypeEntity> contractTypeMap = contractTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 4. 按合同类型分组模板
        Map<Integer, List<ContractTemplateEntity>> typeTemplatesMap = draftTemplates.stream()
                .collect(Collectors.groupingBy(
                        template -> template.getContractTypeLevel3() != null ? template.getContractTypeLevel3() :
                                template.getContractTypeLevel2() != null ? template.getContractTypeLevel2() :
                                        template.getContractTypeLevel1()
                ));

        // 5. 构建返回结果
        ContractTemplateDraftListRespDTO result = new ContractTemplateDraftListRespDTO();
        List<ContractTemplateDraftListRespDTO.ContractTypeGroup> groups = new ArrayList<>();

        typeTemplatesMap.forEach((typeId, templates) -> {
            ContractTypeEntity contractType = contractTypeMap.get(typeId);
            if (contractType != null) {
                ContractTemplateDraftListRespDTO.ContractTypeGroup group = new ContractTemplateDraftListRespDTO.ContractTypeGroup();
                group.setContractTypeId(typeId);
                group.setContractTypeName(contractType.getTypeName());

                List<ContractTemplateDraftListRespDTO.TemplateDraft> draftList = templates.stream()
                        .map(template -> {
                            ContractTemplateDraftListRespDTO.TemplateDraft draft = new ContractTemplateDraftListRespDTO.TemplateDraft();
                            draft.setTemplateId(template.getTemplateId());
                            draft.setTemplateName(template.getTemplateName());
                            draft.setTemplateCode(template.getTemplateCode());
                            draft.setUsageInstructions(template.getUsageInstructions());
                            draft.setCreatedAt(template.getCreatedAt());
                            draft.setUpdatedAt(template.getUpdatedAt());
                            
                            // 直接从模板的content字段获取表单数据
                            try {
                                if (template.getContent() != null && !template.getContent().trim().isEmpty()) {
                                    // 直接解析JSON字符串，不做任何处理
                                    ContractFormDataDTO formDataDTO = JSON.parseObject(template.getContent(), ContractFormDataDTO.class);
                                    draft.setContent(formDataDTO);
                                } else {
                                    draft.setContent(new ContractFormDataDTO()); // 如果content为空，返回空对象
                                }
                            } catch (Exception e) {
                                log.warn("解析草稿模版content失败，模版ID: {}", template.getTemplateId(), e);
                                draft.setContent(new ContractFormDataDTO()); // 返回空对象
                            }
                            
                            return draft;
                        })
                        .collect(Collectors.toList());

                group.setTemplates(draftList);
                groups.add(group);
            }
        });

        result.setContractTypeGroups(groups);
        return result;
    }

    @Override
    public ContractTemplatesByTypeRespDTO getAllTemplatesByType(Long publisherId, Boolean editable) {
        // 1. 获取当前用户信息
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (currentUser == null) {
            log.warn("获取所有模板失败：用户未登录");
            return new ContractTemplatesByTypeRespDTO();
        }

        // 2. 获取用户权限的合同类型ID集合（部门权限 + 用户权限）
        Set<Integer> allowedTypeIds = new HashSet<>();
        
        // 2.1 查询部门权限
        Long mainDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
        if (mainDepartmentId != null) {
            List<ContractTypeDepartmentEntity> departmentPermissions = contractTypeDepartmentService.list(
                    new LambdaQueryWrapper<ContractTypeDepartmentEntity>()
                            .eq(ContractTypeDepartmentEntity::getDepartmentId, mainDepartmentId)
            );
            allowedTypeIds.addAll(departmentPermissions.stream()
                    .map(ContractTypeDepartmentEntity::getContractTypeId)
                    .collect(Collectors.toSet()));
        }
        
        // 2.2 查询用户权限
        List<ContractTypeUser> userPermissions = contractTypeUserService.list(
                new LambdaQueryWrapper<ContractTypeUser>()
                        .eq(ContractTypeUser::getUserId, currentUser.getUserId())
        );
        allowedTypeIds.addAll(userPermissions.stream()
                .map(ContractTypeUser::getContractTypeId)
                .collect(Collectors.toSet()));
        
        if (allowedTypeIds.isEmpty()) {
            log.info("用户 {} 没有任何合同类型权限", currentUser.getUserId());
            return new ContractTemplatesByTypeRespDTO();
        }
        
        log.info("用户 {} 拥有合同类型权限: {}", currentUser.getUserId(), allowedTypeIds);

        // 3. 查询所有已发布的合同模版
        LambdaQueryWrapper<ContractTemplateEntity> templateWrapper = buildBaseTemplateQuery(publisherId, editable);
        List<ContractTemplateEntity> allTemplates = contractTemplateMapper.selectList(templateWrapper);
        
        // 4. 根据权限过滤模板
        List<ContractTemplateEntity> filteredTemplates = allTemplates.stream()
                .filter(template -> {
                    // 检查模板的合同类型是否在用户权限范围内
                    return (template.getContractTypeLevel1() != null && allowedTypeIds.contains(template.getContractTypeLevel1())) ||
                           (template.getContractTypeLevel2() != null && allowedTypeIds.contains(template.getContractTypeLevel2())) ||
                           (template.getContractTypeLevel3() != null && allowedTypeIds.contains(template.getContractTypeLevel3()));
                })
                .collect(Collectors.toList());

        // 5. 查询所有合同类型
        List<ContractTypeEntity> allContractTypes = contractTypeMapper.selectList(
                new LambdaQueryWrapper<ContractTypeEntity>()
                        .eq(ContractTypeEntity::getIsEnabled, true)
                        .orderByAsc(ContractTypeEntity::getTypeOrder)
        );

        // 6. 构建合同类型Map
        Map<Integer, ContractTypeEntity> contractTypeMap = allContractTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 7. 批量获取发布者信息
        Map<Long, LoginCheckVO> publisherInfoMap = batchGetPublisherInfo(filteredTemplates);

        // 8. 构建层级结构
        return buildTemplatesByTypeResponse(null, filteredTemplates, contractTypeMap, publisherInfoMap);
    }

    @Override
    public ContractTemplatesByTypeRespDTO getTemplatesByContractTypeId(Integer contractTypeId, Long publisherId, Boolean editable) {
        // 1. 验证合同类型是否存在
        ContractTypeEntity parentType = contractTypeMapper.selectById(contractTypeId);
        if (parentType == null) {
            throw new RuntimeException("合同类型不存在，ID: " + contractTypeId);
        }

        // 2. 获取当前用户信息
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (currentUser == null) {
            log.warn("获取指定类型模板失败：用户未登录");
            return new ContractTemplatesByTypeRespDTO();
        }

        // 3. 获取用户权限的合同类型ID集合（部门权限 + 用户权限）
        Set<Integer> allowedTypeIds = new HashSet<>();
        
        // 3.1 查询部门权限
        Long mainDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
        if (mainDepartmentId != null) {
            List<ContractTypeDepartmentEntity> departmentPermissions = contractTypeDepartmentService.list(
                    new LambdaQueryWrapper<ContractTypeDepartmentEntity>()
                            .eq(ContractTypeDepartmentEntity::getDepartmentId, mainDepartmentId)
            );
            allowedTypeIds.addAll(departmentPermissions.stream()
                    .map(ContractTypeDepartmentEntity::getContractTypeId)
                    .collect(Collectors.toSet()));
        }
        
        // 3.2 查询用户权限
        List<ContractTypeUser> userPermissions = contractTypeUserService.list(
                new LambdaQueryWrapper<ContractTypeUser>()
                        .eq(ContractTypeUser::getUserId, currentUser.getUserId())
        );
        allowedTypeIds.addAll(userPermissions.stream()
                .map(ContractTypeUser::getContractTypeId)
                .collect(Collectors.toSet()));
        
        if (allowedTypeIds.isEmpty()) {
            log.info("用户 {} 没有任何合同类型权限", currentUser.getUserId());
            return new ContractTemplatesByTypeRespDTO();
        }
        
        log.info("用户 {} 拥有合同类型权限: {}", currentUser.getUserId(), allowedTypeIds);

        // 4. 查询所有已发布的合同模版
        LambdaQueryWrapper<ContractTemplateEntity> templateWrapper = buildBaseTemplateQuery(publisherId, editable);
        List<ContractTemplateEntity> allTemplates = contractTemplateMapper.selectList(templateWrapper);
        
        // 5. 根据权限过滤模板
        List<ContractTemplateEntity> filteredTemplates = allTemplates.stream()
                .filter(template -> {
                    // 检查模板的合同类型是否在用户权限范围内
                    return (template.getContractTypeLevel1() != null && allowedTypeIds.contains(template.getContractTypeLevel1())) ||
                           (template.getContractTypeLevel2() != null && allowedTypeIds.contains(template.getContractTypeLevel2())) ||
                           (template.getContractTypeLevel3() != null && allowedTypeIds.contains(template.getContractTypeLevel3()));
                })
                .collect(Collectors.toList());

        // 6. 查询所有合同类型
        List<ContractTypeEntity> allContractTypes = contractTypeMapper.selectList(
                new LambdaQueryWrapper<ContractTypeEntity>()
                        .eq(ContractTypeEntity::getIsEnabled, true)
                        .orderByAsc(ContractTypeEntity::getTypeOrder)
        );

        // 7. 构建合同类型Map
        Map<Integer, ContractTypeEntity> contractTypeMap = allContractTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 8. 批量获取发布者信息
        Map<Long, LoginCheckVO> publisherInfoMap = batchGetPublisherInfo(filteredTemplates);

        // 9. 构建以指定类型为根的层级结构
        return buildTemplatesByTypeResponse(contractTypeId, filteredTemplates, contractTypeMap, publisherInfoMap);
    }

    @Override
    public ContractTemplatesByTypeRespDTO searchTemplatesByName(String keyword) {
        // 1. 查询所有已发布的且名称包含关键字的合同模版
        LambdaQueryWrapper<ContractTemplateEntity> templateWrapper = new LambdaQueryWrapper<>();
        templateWrapper.eq(ContractTemplateEntity::getStatus, "published")
                .like(ContractTemplateEntity::getTemplateName, keyword)
                .orderByDesc(ContractTemplateEntity::getUpdatedAt);

        // 添加租户隔离条件 - 修改逻辑：优先使用当前租户，如果为空则使用租户列表
        UserInfo currentUser = AuthUtil.getCurrentUser();
        String currentSysTenantKey = currentUser != null ? currentUser.getSysTenantKey() : null;

        if (currentSysTenantKey != null && !currentSysTenantKey.trim().isEmpty()) {
            // 如果当前用户有明确的sysTenantKey，只查询该租户下的数据
            templateWrapper.eq(ContractTemplateEntity::getSysTenantKey, currentSysTenantKey);
        } else {
            // 如果sysTenantKey为null或空，使用原有逻辑（查询用户有权限的所有租户）
            List<String> userTenantKeys = AuthUtil.getUserTenantKeys();
            if (userTenantKeys != null && !userTenantKeys.isEmpty()) {
                templateWrapper.in(ContractTemplateEntity::getSysTenantKey, userTenantKeys);
            } else if (userTenantKeys != null) {
                // 空列表表示没有任何租户权限
                templateWrapper.eq(ContractTemplateEntity::getSysTenantKey, "NO_PERMISSION");
            }
        }

        // 部门权限判定已移除，仅保留租户隔离

        List<ContractTemplateEntity> matchedTemplates = contractTemplateMapper.selectList(templateWrapper);

        if (matchedTemplates.isEmpty()) {
            return new ContractTemplatesByTypeRespDTO();
        }

        // 2. 收集所有相关的合同类型ID
        Set<Integer> contractTypeIds = new HashSet<>();
        for (ContractTemplateEntity template : matchedTemplates) {
            if (template.getContractTypeLevel1() != null) {
                contractTypeIds.add(template.getContractTypeLevel1());
            }
            if (template.getContractTypeLevel2() != null) {
                contractTypeIds.add(template.getContractTypeLevel2());
            }
            if (template.getContractTypeLevel3() != null) {
                contractTypeIds.add(template.getContractTypeLevel3());
            }
        }

        // 3. 查询所有相关的合同类型
        List<ContractTypeEntity> relatedContractTypes = new ArrayList<>();
        if (!contractTypeIds.isEmpty()) {
            relatedContractTypes.addAll(contractTypeMapper.selectBatchIds(contractTypeIds));
            // 添加所有父级类型
            Set<Integer> parentTypeIds = new HashSet<>();
            for (ContractTypeEntity type : relatedContractTypes) {
                if (type.getParentId() != null) {
                    parentTypeIds.add(type.getParentId());
                }
            }
            if (!parentTypeIds.isEmpty()) {
                // 移除已经存在的类型ID
                parentTypeIds.removeAll(contractTypeIds);
                if (!parentTypeIds.isEmpty()) {
                    relatedContractTypes.addAll(contractTypeMapper.selectBatchIds(parentTypeIds));
                }
            }
        }

        // 4. 构建合同类型Map
        Map<Integer, ContractTypeEntity> contractTypeMap = relatedContractTypes.stream()
                .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

        // 5. 批量获取发布者信息
        Map<Long, LoginCheckVO> publisherInfoMap = batchGetPublisherInfo(matchedTemplates);

        // 6. 构建返回结果
        ContractTemplatesByTypeRespDTO result = new ContractTemplatesByTypeRespDTO();
        List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> topLevelGroups = buildContractTypeTree(
                relatedContractTypes, matchedTemplates, contractTypeMap, publisherInfoMap, null);
        result.setContractTypeGroups(topLevelGroups);

        return result;
    }

    /**
     * 递归构建合同类型树结构，包含模版信息
     */
    private List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> buildContractTypeTree(
            List<ContractTypeEntity> allContractTypes,
            List<ContractTemplateEntity> allTemplates,
            Map<Integer, ContractTypeEntity> contractTypeMap,
            Map<Long, LoginCheckVO> publisherInfoMap,
            Integer parentId) {

        return buildContractTypeTreeWithTargetType(allContractTypes, allTemplates, contractTypeMap, publisherInfoMap, parentId, null);
    }

    /**
     * 递归构建合同类型树结构，包含模版信息（支持目标类型标识）
     */
    private List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> buildContractTypeTreeWithTargetType(
            List<ContractTypeEntity> allContractTypes,
            List<ContractTemplateEntity> allTemplates,
            Map<Integer, ContractTypeEntity> contractTypeMap,
            Map<Long, LoginCheckVO> publisherInfoMap,
            Integer parentId,
            Integer targetTypeId) {

        List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> groups = new ArrayList<>();

        // 找到当前层级的合同类型
        List<ContractTypeEntity> currentLevelTypes = allContractTypes.stream()
                .filter(type -> Objects.equals(type.getParentId(), parentId))
                .collect(Collectors.toList());

        for (ContractTypeEntity contractType : currentLevelTypes) {
            ContractTemplatesByTypeRespDTO.ContractTypeGroup group = new ContractTemplatesByTypeRespDTO.ContractTypeGroup();
            group.setContractTypeId(contractType.getId());
            group.setContractTypeName(contractType.getTypeName());
            group.setParentId(contractType.getParentId());

            // 确定层级
            Integer level = calculateLevel(contractType, contractTypeMap);
            group.setLevel(level);

            // 查找当前类型下的子类型
            List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> children = buildContractTypeTreeWithTargetType(
                    allContractTypes, allTemplates, contractTypeMap, publisherInfoMap, contractType.getId(), targetTypeId);
            group.setChildren(children);

            // 查找当前类型下的模版 - 统一使用最深层级匹配逻辑
            List<ContractTemplatesByTypeRespDTO.TemplateInfo> templates = findTemplatesForContractType(
                    contractType.getId(), level, allTemplates, publisherInfoMap);

            group.setTemplates(templates);

            // 只有当该类型有模板或有包含模板的子类型时才添加到结果中
            if (!templates.isEmpty() || hasTemplatesInChildren(children)) {
                groups.add(group);
            }
        }

        return groups;
    }

    /**
     * 检查子节点中是否有模板
     */
    private boolean hasTemplatesInChildren(List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> children) {
        if (children == null || children.isEmpty()) {
            return false;
        }

        for (ContractTemplatesByTypeRespDTO.ContractTypeGroup child : children) {
            // 如果子节点有模板，或者子节点的子节点有模板，则返回true
            if (!child.getTemplates().isEmpty() || hasTemplatesInChildren(child.getChildren())) {
                return true;
            }
        }

        return false;
    }


    /**
     * 计算合同类型的层级
     */
    private Integer calculateLevel(ContractTypeEntity contractType, Map<Integer, ContractTypeEntity> contractTypeMap) {
        if (contractType.getParentId() == null) {
            return 1; // 一级类型
        }

        ContractTypeEntity parent = contractTypeMap.get(contractType.getParentId());
        if (parent != null && parent.getParentId() == null) {
            return 2; // 二级类型
        }

        return 3; // 三级类型
    }

    /**
     * 查找指定合同类型下的模版
     */
    private List<ContractTemplatesByTypeRespDTO.TemplateInfo> findTemplatesForContractType(
            Integer contractTypeId, Integer level, List<ContractTemplateEntity> allTemplates, Map<Long, LoginCheckVO> publisherInfoMap) {

        return allTemplates.stream()
                .filter(template -> isTemplateMatchingContractType(template, contractTypeId, level))
                .map(template -> convertToTemplateInfo(template, publisherInfoMap))
                .collect(Collectors.toList());
    }

    /**
     * 判断模版是否匹配指定的合同类型
     * 只有当合同类型是模版的最深层级时，才返回匹配
     */
    private boolean isTemplateMatchingContractType(ContractTemplateEntity template, Integer contractTypeId, Integer level) {
        // 确定模版的最深层级
        Integer templateDeepestLevel = getTemplateDeepestLevel(template);
        Integer templateDeepestTypeId = getTemplateTypeIdByLevel(template, templateDeepestLevel);

        // 只有当查询的类型ID和层级正好是模版的最深层级时，才匹配
        return Objects.equals(contractTypeId, templateDeepestTypeId) && Objects.equals(level, templateDeepestLevel);
    }

    /**
     * 获取模版的最深层级
     */
    private Integer getTemplateDeepestLevel(ContractTemplateEntity template) {
        if (template.getContractTypeLevel3() != null) {
            return 3;
        } else if (template.getContractTypeLevel2() != null) {
            return 2;
        } else if (template.getContractTypeLevel1() != null) {
            return 1;
        } else {
            return null; // 没有设置合同类型
        }
    }

    /**
     * 根据层级获取模版的合同类型ID
     */
    private Integer getTemplateTypeIdByLevel(ContractTemplateEntity template, Integer level) {
        if (level == null) {
            return null;
        }
        switch (level) {
            case 1:
                return template.getContractTypeLevel1();
            case 2:
                return template.getContractTypeLevel2();
            case 3:
                return template.getContractTypeLevel3();
            default:
                return null;
        }
    }



    /**
     * 批量获取发布者信息
     */
    private Map<Long, LoginCheckVO> batchGetPublisherInfo(List<ContractTemplateEntity> templates) {
        // 收集所有非空的发布者ID
        Set<Long> publisherIds = templates.stream()
                .map(ContractTemplateEntity::getPublisherId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        return batchGetPublisherInfo(publisherIds);
    }

    /**
     * 批量获取发布者信息（根据发布者ID集合）
     */
    private Map<Long, LoginCheckVO> batchGetPublisherInfo(Set<Long> publisherIds) {
        if (publisherIds.isEmpty()) {
            return new HashMap<>();
        }

        try {
            // 批量获取详细用户信息
            EmployeeQueryById queryRequest = new EmployeeQueryById();
            queryRequest.setEmployeeIds(new ArrayList<>(publisherIds));
            List<EmployeeQueryShowVO> employees = sysUserService.queryEmployeeShow(queryRequest);

            // 转换为LoginCheckVO并构建映射（处理重复key的情况）
            Map<Long, LoginCheckVO> userInfoMap = employees.stream()
                    .collect(Collectors.toMap(
                            EmployeeQueryShowVO::getId,
                            employee -> {
                                LoginCheckVO loginCheckVO = new LoginCheckVO();
                                loginCheckVO.setId(employee.getId());
                                loginCheckVO.setName(employee.getName());
                                loginCheckVO.setAliasName(employee.getName()); // 使用name作为nickName
                                loginCheckVO.setAvatar(employee.getAvatar());
                                return loginCheckVO;
                            },
                            (existing, replacement) -> existing // 当有重复key时，保留第一个
                    ));

            return userInfoMap;
        } catch (Exception e) {
            log.error("批量获取发布者信息失败", e);
            return new HashMap<>();
        }
    }

    /**
     * 批量获取文件信息
     */
    private Map<Integer, FileVO> batchGetFileInfo(Set<Integer> fileIds) {
        if (fileIds.isEmpty()) {
            return new HashMap<>();
        }

        Map<Integer, FileVO> fileInfoMap = new HashMap<>();
        
        try {
            for (Integer fileId : fileIds) {
                try {
                    SingleResponse<FileVO> fileResult = fileInfoService.getFileInfoById(fileId.toString());
                    if (fileResult.isSuccess() && fileResult.getData() != null) {
                        fileInfoMap.put(fileId, fileResult.getData());
                    }
                } catch (Exception e) {
                    log.warn("获取文件信息失败，文件ID: {}", fileId, e);
                }
            }
        } catch (Exception e) {
            log.error("批量获取文件信息失败", e);
        }

        return fileInfoMap;
    }

    /**
     * 获取单个用户信息
     */
    private LoginCheckVO getSingleUserInfo(Long userId) {
        try {
            // 使用本地服务获取用户信息
            EmployeeQueryById queryRequest = new EmployeeQueryById();
            queryRequest.setEmployeeIds(Collections.singletonList(userId));
            List<EmployeeQueryShowVO> employees = sysUserService.queryEmployeeShow(queryRequest);

            if (!employees.isEmpty()) {
                EmployeeQueryShowVO employee = employees.get(0);
                LoginCheckVO loginCheckVO = new LoginCheckVO();
                loginCheckVO.setId(employee.getId());
                loginCheckVO.setName(employee.getName());
                loginCheckVO.setAliasName(employee.getAliasName());
                loginCheckVO.setAvatar(employee.getAvatar());
                return loginCheckVO;
            }
        } catch (Exception e) {
            log.warn("获取用户信息失败，用户ID: {}", userId, e);
        }
        return null;
    }

    /**
     * 转换模版实体为模版信息DTO
     */
    private ContractTemplatesByTypeRespDTO.TemplateInfo convertToTemplateInfo(ContractTemplateEntity template, Map<Long, LoginCheckVO> publisherInfoMap) {
        ContractTemplatesByTypeRespDTO.TemplateInfo templateInfo = new ContractTemplatesByTypeRespDTO.TemplateInfo();
        templateInfo.setTemplateId(template.getTemplateId());
        templateInfo.setTemplateName(template.getTemplateName());
        templateInfo.setTemplateCode(template.getTemplateCode());
        templateInfo.setUsageInstructions(template.getUsageInstructions());
        templateInfo.setStatus(template.getStatus());
        templateInfo.setEditableWhenCreating(template.getEditableWhenCreating());
        templateInfo.setCreatedAt(template.getCreatedAt());
        templateInfo.setUpdatedAt(template.getUpdatedAt());
        templateInfo.setPublisherId(template.getPublisherId());

        // 处理文件信息
        if (template.getTemplateFileId() != null) {
            SingleResponse<FileVO> fileResult = fileInfoService.getFileInfoById(template.getTemplateFileId().toString());
            if (fileResult.isSuccess()) {
                FileVO fileInfo = fileResult.getData();
                templateInfo.setFileInfo(fileInfo);
                // 设置templateFileUrl为fileKey
                templateInfo.setTemplateFileUrl(fileInfo.getFileKey());
                // 设置templateFileName为文件名
                templateInfo.setTemplateFileName(fileInfo.getFileName());
            }
        }

        // 填充发布者信息
        if (template.getPublisherId() != null && publisherInfoMap.containsKey(template.getPublisherId())) {
            LoginCheckVO loginCheckVO = publisherInfoMap.get(template.getPublisherId());
            templateInfo.setPublisherName(loginCheckVO.getName());
            templateInfo.setPublisherAliasName(loginCheckVO.getAliasName());
            templateInfo.setPublisherAvatar(loginCheckVO.getAvatar());
        }

        // 设置最后一级的合同类型ID
        Integer lastLevelTypeId = getTemplateDeepestContractTypeId(template);
        templateInfo.setContractTypeId(lastLevelTypeId);

        // 直接从模板的content字段获取表单数据
        try {
            if (template.getContent() != null && !template.getContent().trim().isEmpty()) {
                // 直接解析JSON字符串，不做任何处理
                ContractFormDataDTO formDataDTO = JSON.parseObject(template.getContent(), ContractFormDataDTO.class);
                templateInfo.setContent(formDataDTO);
            } else {
                templateInfo.setContent(new ContractFormDataDTO()); // 如果content为空，返回空对象
            }
        } catch (Exception e) {
            log.warn("解析模版列表中的模版content失败，模版ID: {}", template.getTemplateId(), e);
            templateInfo.setContent(new ContractFormDataDTO()); // 返回空对象
        }

        return templateInfo;
    }

    /**
     * 构建基础的模板查询条件
     */
    private LambdaQueryWrapper<ContractTemplateEntity> buildBaseTemplateQuery(Long publisherId, Boolean editable) {
        LambdaQueryWrapper<ContractTemplateEntity> templateWrapper = new LambdaQueryWrapper<>();
        templateWrapper.eq(ContractTemplateEntity::getStatus, "published")
                .orderByDesc(ContractTemplateEntity::getUpdatedAt);

        // 添加租户隔离条件 - 修改逻辑：优先使用当前租户，如果为空则使用租户列表
        UserInfo currentUser = AuthUtil.getCurrentUser();
        String currentSysTenantKey = currentUser != null ? currentUser.getSysTenantKey() : null;

        if (currentSysTenantKey != null && !currentSysTenantKey.trim().isEmpty()) {
            // 如果当前用户有明确的sysTenantKey，只查询该租户下的数据
            templateWrapper.eq(ContractTemplateEntity::getSysTenantKey, currentSysTenantKey);
        } else {
            // 如果sysTenantKey为null或空，使用原有逻辑（查询用户有权限的所有租户）
            List<String> userTenantKeys = AuthUtil.getUserTenantKeys();
            if (userTenantKeys != null && !userTenantKeys.isEmpty()) {
                templateWrapper.in(ContractTemplateEntity::getSysTenantKey, userTenantKeys);
            } else if (userTenantKeys != null) {
                // 空列表表示没有任何租户权限
                templateWrapper.eq(ContractTemplateEntity::getSysTenantKey, "NO_PERMISSION");
            }
        }

        // 部门权限判定已移除，仅保留租户隔离

        // 添加发布人筛选条件
        if (publisherId != null) {
            templateWrapper.eq(ContractTemplateEntity::getPublisherId, publisherId);
        }

        // 添加是否可修改筛选条件
        if (editable != null) {
            templateWrapper.eq(ContractTemplateEntity::getEditableWhenCreating, editable);
        }

        return templateWrapper;
    }

    // 部门权限判定方法已移除，现在仅保留租户隔离
    


    /**
     * 构建基础的模板查询条件（支持模糊搜索）
     */
    private LambdaQueryWrapper<ContractTemplateEntity> buildBaseTemplateQuery(Long publisherId, Boolean editable, String keyword) {
        LambdaQueryWrapper<ContractTemplateEntity> wrapper = buildBaseTemplateQuery(publisherId, editable);

        // 添加模板名称模糊匹配条件
        if (StringUtils.isNotBlank(keyword)) {
            wrapper.like(ContractTemplateEntity::getTemplateName, keyword);
        }

        return wrapper;
    }

    @Override
    public ContractTemplatesByTypeRespDTO getTemplatesByContractTypeId(Integer contractTypeId, Long publisherId, Boolean editable, String keyword) {
        // 1. 参数验证
        if (contractTypeId == null) {
            throw new IllegalArgumentException("合同类型ID不能为空");
        }

        ContractTypeEntity parentType = contractTypeMapper.selectById(contractTypeId);
        if (parentType == null) {
            throw new IllegalArgumentException("合同类型不存在，ID: " + contractTypeId);
        }

        // 2. 统一调用通用查询方法
        return queryTemplates(contractTypeId, publisherId, editable, keyword);
    }

    @Override
    public ContractTemplatesByTypeRespDTO getAllTemplatesByType(Long publisherId, Boolean editable, String keyword) {
        // 调用通用查询方法，contractTypeId传null表示查询所有
        return queryTemplates(null, publisherId, editable, keyword);
    }

    /**
     * 统一的模板查询方法
     */
    private ContractTemplatesByTypeRespDTO queryTemplates(Integer contractTypeId, Long publisherId, Boolean editable, String keyword) {
        try {
            // 1. 参数验证
            validateQueryParams(publisherId, editable, keyword);

            // 2. 查询模板数据
            LambdaQueryWrapper<ContractTemplateEntity> templateWrapper = buildBaseTemplateQuery(publisherId, editable, keyword);
            List<ContractTemplateEntity> allTemplates = contractTemplateMapper.selectList(templateWrapper);

            if (allTemplates.isEmpty()) {
                log.info("未查询到符合条件的模板，contractTypeId: {}, publisherId: {}, editable: {}, keyword: {}",
                        contractTypeId, publisherId, editable, keyword);
                return new ContractTemplatesByTypeRespDTO();
            }

            // 2.1 根据当前用户主部门权限过滤模板
            UserInfo currentUser = AuthUtil.getCurrentUser();
            if (currentUser == null || currentUser.getId() == null) {
                log.warn("无法获取当前用户信息，返回空的模板列表");
                return new ContractTemplatesByTypeRespDTO();
            }

            Long mainDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
            if (mainDepartmentId == null) {
                log.warn("用户 {} 没有主部门信息，返回空的模板列表", currentUser.getId());
                return new ContractTemplatesByTypeRespDTO();
            }

            // 查询当前部门可用的合同类型ID列表
            List<ContractTypeDepartmentEntity> typeDepartments = contractTypeDepartmentService.list(
                    new LambdaQueryWrapper<ContractTypeDepartmentEntity>()
                            .eq(ContractTypeDepartmentEntity::getDepartmentId, mainDepartmentId)
            );

            if (typeDepartments.isEmpty()) {
                log.debug("部门 {} 没有关联任何合同类型", mainDepartmentId);
                return new ContractTemplatesByTypeRespDTO();
            }

            // 提取合同类型ID集合
            Set<Integer> allowedTypeIds = typeDepartments.stream()
                    .map(ContractTypeDepartmentEntity::getContractTypeId)
                    .collect(Collectors.toSet());

            // 过滤模板：只保留当前用户主部门匹配的合同类型的模板
            int originalSize = allTemplates.size();
            allTemplates = allTemplates.stream()
                    .filter(template -> {
                        Integer templateTypeId = getTemplateDeepestContractTypeId(template);
                        return templateTypeId != null && allowedTypeIds.contains(templateTypeId);
                    })
                    .collect(Collectors.toList());

            log.debug("部门 {} 过滤前模板数量: {}, 过滤后数量: {}", mainDepartmentId, originalSize, allTemplates.size());

            if (allTemplates.isEmpty()) {
                log.info("根据部门权限过滤后，没有符合条件的模板");
                return new ContractTemplatesByTypeRespDTO();
            }

            // 3. 查询合同类型数据
            List<ContractTypeEntity> allContractTypes = contractTypeMapper.selectList(
                    new LambdaQueryWrapper<ContractTypeEntity>()
                            .eq(ContractTypeEntity::getIsEnabled, true)
                            .orderByAsc(ContractTypeEntity::getTypeOrder)
            );

            Map<Integer, ContractTypeEntity> contractTypeMap = allContractTypes.stream()
                    .collect(Collectors.toMap(ContractTypeEntity::getId, type -> type));

            // 4. 批量获取发布者信息
            Map<Long, LoginCheckVO> publisherInfoMap = batchGetPublisherInfo(allTemplates);

            // 5. 构建结果
            return buildTemplatesByTypeResponse(contractTypeId, allTemplates, contractTypeMap, publisherInfoMap);

        } catch (IllegalArgumentException e) {
            // 参数异常直接抛出
            throw e;
        } catch (Exception e) {
            log.error("查询模板失败，contractTypeId: {}, publisherId: {}, editable: {}, keyword: {}",
                    contractTypeId, publisherId, editable, keyword, e);
            throw new RuntimeException("查询模板失败: " + e.getMessage(), e);
        }
    }

    /**
     * 验证查询参数
     */
    private void validateQueryParams(Long publisherId, Boolean editable, String keyword) {
        // 验证发布人ID
        if (publisherId != null && publisherId <= 0) {
            throw new IllegalArgumentException("发布人ID必须大于0");
        }

        // 验证关键词长度
        if (keyword != null && keyword.trim().length() > 100) {
            throw new IllegalArgumentException("搜索关键词长度不能超过100字符");
        }

        // 可以根据需要添加更多验证规则
    }

    /**
     * 构建层级结构
     */
    private ContractTemplatesByTypeRespDTO buildTemplatesByTypeResponse(Integer contractTypeId, List<ContractTemplateEntity> allTemplates, Map<Integer, ContractTypeEntity> contractTypeMap, Map<Long, LoginCheckVO> publisherInfoMap) {
        ContractTemplatesByTypeRespDTO result = new ContractTemplatesByTypeRespDTO();

        if (contractTypeId == null) {
            // 查询所有类型的模板 - 不做额外过滤，直接使用传入的模板列表
            List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> topLevelGroups = buildContractTypeTreeForAllTemplates(
                    contractTypeMapper.selectList(new LambdaQueryWrapper<ContractTypeEntity>()
                            .eq(ContractTypeEntity::getIsEnabled, true)
                            .orderByAsc(ContractTypeEntity::getTypeOrder)
                    ), allTemplates, contractTypeMap, publisherInfoMap, null);
            result.setContractTypeGroups(topLevelGroups);
        } else {
            // 查询指定类型及其所有子类型下的模板，同时包含上级类型结构
            Set<Integer> targetTypeIds = getTypeAndAllSubTypeIds(contractTypeId, contractTypeMap);

            // 获取完整的类型层级结构（包含上级类型）
            Set<Integer> allRelevantTypeIds = getCompleteTypeHierarchy(contractTypeId, contractTypeMap, targetTypeIds);

            // 过滤相关的合同类型
            List<ContractTypeEntity> relevantTypes = contractTypeMapper.selectList(
                    new LambdaQueryWrapper<ContractTypeEntity>()
                            .eq(ContractTypeEntity::getIsEnabled, true)
                            .in(ContractTypeEntity::getId, allRelevantTypeIds)
                            .orderByAsc(ContractTypeEntity::getTypeOrder)
            );

            // 过滤相关的模板（只查找目标类型及其子类型的模板）
            List<ContractTemplateEntity> relevantTemplates = allTemplates.stream()
                    .filter(template -> isTemplateInTargetTypes(template, targetTypeIds))
                    .collect(Collectors.toList());

            // 找到最顶层的父类型，从那里开始构建树
            Integer topLevelParentId = getTopLevelParentId(contractTypeId, contractTypeMap);

            // 构建完整的层级结构，传递目标类型ID
            List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> groups = buildContractTypeTreeWithTargetType(
                    relevantTypes, relevantTemplates, contractTypeMap, publisherInfoMap, topLevelParentId, contractTypeId);
            result.setContractTypeGroups(groups);
        }

        return result;
    }

    /**
     * 构建合同类型树结构，用于查询所有模板（不做额外过滤）
     */
    private List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> buildContractTypeTreeForAllTemplates(
            List<ContractTypeEntity> allContractTypes,
            List<ContractTemplateEntity> allTemplates,
            Map<Integer, ContractTypeEntity> contractTypeMap,
            Map<Long, LoginCheckVO> publisherInfoMap,
            Integer parentId) {

        List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> groups = new ArrayList<>();

        // 找到当前层级的合同类型
        List<ContractTypeEntity> currentLevelTypes = allContractTypes.stream()
                .filter(type -> Objects.equals(type.getParentId(), parentId))
                .collect(Collectors.toList());

        for (ContractTypeEntity contractType : currentLevelTypes) {
            ContractTemplatesByTypeRespDTO.ContractTypeGroup group = new ContractTemplatesByTypeRespDTO.ContractTypeGroup();
            group.setContractTypeId(contractType.getId());
            group.setContractTypeName(contractType.getTypeName());
            group.setParentId(contractType.getParentId());

            // 确定层级
            Integer level = calculateLevel(contractType, contractTypeMap);
            group.setLevel(level);

            // 查找当前类型下的子类型
            List<ContractTemplatesByTypeRespDTO.ContractTypeGroup> children = buildContractTypeTreeForAllTemplates(
                    allContractTypes, allTemplates, contractTypeMap, publisherInfoMap, contractType.getId());
            group.setChildren(children);

            // 查找当前类型下的模版 - 使用更宽松的匹配条件
            List<ContractTemplatesByTypeRespDTO.TemplateInfo> templates = findAllTemplatesForContractType(
                    contractType.getId(), level, allTemplates, publisherInfoMap);
            group.setTemplates(templates);

            // 只有当该类型有模板或有包含模板的子类型时才添加到结果中
            if (!templates.isEmpty() || hasTemplatesInChildren(children)) {
                groups.add(group);
            }
        }

        return groups;
    }

    /**
     * 查找指定合同类型下的模版（只匹配最深层级）
     */
    private List<ContractTemplatesByTypeRespDTO.TemplateInfo> findAllTemplatesForContractType(
            Integer contractTypeId, Integer level, List<ContractTemplateEntity> allTemplates, Map<Long, LoginCheckVO> publisherInfoMap) {

        return allTemplates.stream()
                .filter(template -> isTemplateMatchingContractType(template, contractTypeId, level))
                .map(template -> convertToTemplateInfo(template, publisherInfoMap))
                .collect(Collectors.toList());
    }

    /**
     * 获取指定类型及其所有子类型的ID集合
     */
    private Set<Integer> getTypeAndAllSubTypeIds(Integer typeId, Map<Integer, ContractTypeEntity> contractTypeMap) {
        Set<Integer> result = new HashSet<>();
        result.add(typeId);

        // 递归查找所有子类型
        addSubTypeIds(typeId, contractTypeMap, result);

        return result;
    }

    /**
     * 获取完整的类型层级结构（包含上级类型和下级类型）
     */
    private Set<Integer> getCompleteTypeHierarchy(Integer targetTypeId, Map<Integer, ContractTypeEntity> contractTypeMap, Set<Integer> subTypeIds) {
        Set<Integer> result = new HashSet<>(subTypeIds);

        // 添加所有父级类型
        addAllParentTypeIds(targetTypeId, contractTypeMap, result);

        return result;
    }

    /**
     * 递归添加所有父级类型ID
     */
    private void addAllParentTypeIds(Integer typeId, Map<Integer, ContractTypeEntity> contractTypeMap, Set<Integer> result) {
        ContractTypeEntity type = contractTypeMap.get(typeId);
        if (type != null && type.getParentId() != null) {
            result.add(type.getParentId());
            // 递归添加上级父类型
            addAllParentTypeIds(type.getParentId(), contractTypeMap, result);
        }
    }

    /**
     * 获取最顶层的父类型ID
     */
    private Integer getTopLevelParentId(Integer typeId, Map<Integer, ContractTypeEntity> contractTypeMap) {
        ContractTypeEntity type = contractTypeMap.get(typeId);
        if (type == null) {
            return null;
        }

        // 如果当前类型没有父类型，说明它就是顶层类型
        if (type.getParentId() == null) {
            return null; // 返回null表示从根节点开始构建
        }

        // 递归查找最顶层的父类型
        Integer currentId = typeId;
        while (true) {
            ContractTypeEntity currentType = contractTypeMap.get(currentId);
            if (currentType == null || currentType.getParentId() == null) {
                // 找到了最顶层，返回null（表示从根节点开始）
                return null;
            }
            currentId = currentType.getParentId();
        }
    }

    /**
     * 递归添加子类型ID
     */
    private void addSubTypeIds(Integer parentId, Map<Integer, ContractTypeEntity> contractTypeMap, Set<Integer> result) {
        for (ContractTypeEntity type : contractTypeMap.values()) {
            if (Objects.equals(type.getParentId(), parentId)) {
                result.add(type.getId());
                // 递归查找该类型的子类型
                addSubTypeIds(type.getId(), contractTypeMap, result);
            }
        }
    }

    /**
     * 判断模板是否属于目标类型集合
     */
    private boolean isTemplateInTargetTypes(ContractTemplateEntity template, Set<Integer> targetTypeIds) {
        // 检查模板的最深层级类型是否在目标类型集合中
        Integer deepestLevel = getTemplateDeepestLevel(template);
        if (deepestLevel == null) {
            return false;
        }

        Integer templateTypeId = getTemplateTypeIdByLevel(template, deepestLevel);
        return templateTypeId != null && targetTypeIds.contains(templateTypeId);
    }
    
    /**
     * 获取合同模版的最深层级合同类型ID
     *
     * @param template 合同模版实体
     * @return 最深层级的合同类型ID
     */
    private Integer getTemplateDeepestContractTypeId(ContractTemplateEntity template) {
        if (template.getContractTypeLevel3() != null) {
            return template.getContractTypeLevel3();
        } else if (template.getContractTypeLevel2() != null) {
            return template.getContractTypeLevel2();
        } else if (template.getContractTypeLevel1() != null) {
            return template.getContractTypeLevel1();
        }
        return null;
    }

    /**
     * 根据合同类型ID查找对应的工作流ID
     *
     * @param contractTypeId 合同类型ID
     * @return 工作流ID，如果没有找到返回null
     */
    private Long findWorkflowIdByContractTypeId(Integer contractTypeId) {
        LambdaQueryWrapper<ContractWorkflowTypeEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ContractWorkflowTypeEntity::getContractTypeId, contractTypeId)
                .last("LIMIT 1");

        ContractWorkflowTypeEntity workflowType = contractWorkflowTypeService.getOne(queryWrapper);
        return workflowType != null ? workflowType.getWorkflowId() : null;
    }

    /**
     * 根据工作流ID构建模块字段树
     *
     * @param workflowId 工作流ID
     * @return 模块字段树列表
     */
    private List<ContractTemplateRespDTO.TemplateModuleFieldTreeDTO> buildModuleFieldTreeByWorkflowId(Long workflowId) {
        // 1. 查询工作流相关的表单字段
        // is_hidden=0(不隐藏)，is_enabled=1(可用)，is_deleted=0(未删除)
        List<ContractWorkflowFormFieldEntity> workflowFormFields = contractWorkflowFormFieldService.list(
                new LambdaQueryWrapper<ContractWorkflowFormFieldEntity>()
                        .eq(ContractWorkflowFormFieldEntity::getWorkflowId, workflowId)
                        .eq(ContractWorkflowFormFieldEntity::getIsHidden, false)
                        .eq(ContractWorkflowFormFieldEntity::getIsEnabled, true)
                        .eq(ContractWorkflowFormFieldEntity::getIsDeleted, false)
                        .orderByAsc(ContractWorkflowFormFieldEntity::getFieldOrder)
        );

        if (CollectionUtils.isEmpty(workflowFormFields)) {
            log.info("工作流没有配置表单字段，工作流ID: {}", workflowId);
            return new ArrayList<>();
        }

        log.info("查询到工作流表单字段数量: {}, 工作流ID: {}", workflowFormFields.size(), workflowId);

        // 2. 查询工作流配置的字段信息，识别group类型字段
        Set<Long> initialFieldIds = workflowFormFields.stream()
                .map(ContractWorkflowFormFieldEntity::getFieldId)
                .collect(Collectors.toSet());

        List<ContractFieldEntity> initialFields = contractFieldService.list(
                new LambdaQueryWrapper<ContractFieldEntity>()
                        .in(ContractFieldEntity::getId, initialFieldIds)
                        .eq(ContractFieldEntity::getIsEnabled, true)
        );

        // 3. 查找group类型字段并获取其所有子字段，以及查找子字段的父字段
        Set<Long> allFieldIds = new HashSet<>(initialFieldIds);
        List<ContractFieldEntity> allFields = new ArrayList<>(initialFields);

        // 查找group类型字段
        List<Long> groupFieldIds = initialFields.stream()
                .filter(field -> "GROUP".equals(field.getFieldType()))
                .map(ContractFieldEntity::getId)
                .collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(groupFieldIds)) {
            // 查询group字段下的所有子字段
            List<ContractFieldEntity> childFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .in(ContractFieldEntity::getParentFieldId, groupFieldIds)
                            .eq(ContractFieldEntity::getIsEnabled, true)
            );

            // 将子字段添加到总字段列表中
            for (ContractFieldEntity childField : childFields) {
                if (!allFieldIds.contains(childField.getId())) {
                    allFieldIds.add(childField.getId());
                    allFields.add(childField);
                }
            }
        }

        // 查找所有有parent_field_id的字段的父字段
        Set<Long> parentFieldIdsToAdd = new HashSet<>();
        for (ContractFieldEntity field : allFields) {
            if (field.getParentFieldId() != null) {
                // 检查父字段是否已经在列表中
                boolean parentExists = allFieldIds.contains(field.getParentFieldId());
                if (!parentExists) {
                    parentFieldIdsToAdd.add(field.getParentFieldId());
                    log.info("字段 {} (ID: {}) 的父字段 {} 不在列表中，需要添加",
                            field.getFieldName(), field.getId(), field.getParentFieldId());
                }
            }
        }

        // 查询并添加缺失的父字段
        if (!parentFieldIdsToAdd.isEmpty()) {
            List<ContractFieldEntity> parentFields = contractFieldService.list(
                    new LambdaQueryWrapper<ContractFieldEntity>()
                            .in(ContractFieldEntity::getId, parentFieldIdsToAdd)
                            .eq(ContractFieldEntity::getIsEnabled, true)
            );

            for (ContractFieldEntity parentField : parentFields) {
                if (!allFieldIds.contains(parentField.getId())) {
                    allFieldIds.add(parentField.getId());
                    allFields.add(parentField);
                    log.info("添加缺失的父字段: {} (ID: {}, 类型: {})",
                            parentField.getFieldName(), parentField.getId(), parentField.getFieldType());

                    // 如果父字段是GROUP类型，还需要查询它的所有子字段
                    if ("GROUP".equals(parentField.getFieldType())) {
                        List<ContractFieldEntity> additionalChildren = contractFieldService.list(
                                new LambdaQueryWrapper<ContractFieldEntity>()
                                        .eq(ContractFieldEntity::getParentFieldId, parentField.getId())
                                        .eq(ContractFieldEntity::getIsEnabled, true)
                        );

                        for (ContractFieldEntity child : additionalChildren) {
                            if (!allFieldIds.contains(child.getId())) {
                                allFieldIds.add(child.getId());
                                allFields.add(child);
                                log.info("添加GROUP字段 {} 的子字段: {} (ID: {})",
                                        parentField.getFieldName(), child.getFieldName(), child.getId());
                            }
                        }
                    }
                }
            }
        }

        // 4. 按模块ID分组
        Map<Integer, List<ContractWorkflowFormFieldEntity>> moduleFieldMap = workflowFormFields.stream()
                .collect(Collectors.groupingBy(ContractWorkflowFormFieldEntity::getModuleId));

        // 5. 查询所有相关的模块信息
        Set<Integer> moduleIds = moduleFieldMap.keySet();
        List<ContractModuleEntity> modules = contractModuleService.list(
                new LambdaQueryWrapper<ContractModuleEntity>()
                        .in(ContractModuleEntity::getId, moduleIds)
                        .eq(ContractModuleEntity::getIsEnabled, true)
                        .orderByAsc(ContractModuleEntity::getModuleOrder)
        );

        // 6. 构建字段映射
        Map<Long, ContractFieldEntity> fieldMap = allFields.stream()
                .collect(Collectors.toMap(ContractFieldEntity::getId, field -> field));

        // 7. 查询模块字段关联信息（包括新增的子字段）
        List<ContractModuleFieldEntity> moduleFields = contractModuleFieldService.list(
                new LambdaQueryWrapper<ContractModuleFieldEntity>()
                        .in(ContractModuleFieldEntity::getModuleId, moduleIds)
                        .in(ContractModuleFieldEntity::getFieldId, allFieldIds)
        );

        Map<String, ContractModuleFieldEntity> moduleFieldMap2 = moduleFields.stream()
                .collect(Collectors.toMap(
                        mf -> mf.getModuleId() + "_" + mf.getFieldId(),
                        mf -> mf
                ));

        // 8. 构建模块字段树
        List<ContractTemplateRespDTO.TemplateModuleFieldTreeDTO> result = new ArrayList<>();

        for (ContractModuleEntity module : modules) {
            List<ContractWorkflowFormFieldEntity> moduleWorkflowFields = moduleFieldMap.get(module.getId());
            if (CollectionUtils.isEmpty(moduleWorkflowFields)) {
                continue;
            }

            // 构建字段树（传入完整的字段信息，包括group字段的子字段）
            List<ContractTemplateRespDTO.TemplateFieldTreeDTO> fieldTree =
                    buildFieldTreeWithGroupChildren(moduleWorkflowFields, fieldMap, moduleFieldMap2, module.getId());

            // 只有当模块有字段时才添加到结果中
            if (!CollectionUtils.isEmpty(fieldTree)) {
                ContractTemplateRespDTO.TemplateModuleFieldTreeDTO moduleDTO =
                        new ContractTemplateRespDTO.TemplateModuleFieldTreeDTO();
                moduleDTO.setModuleId(module.getId());
                moduleDTO.setModuleName(module.getModuleName());
                moduleDTO.setModuleDescription(module.getModuleDescription());
                moduleDTO.setModuleOrder(module.getModuleOrder());
                moduleDTO.setFields(fieldTree);

                result.add(moduleDTO);
            }
        }


        return result;
    }

    /**
     * 构建字段树
     *
     * @param workflowFields 工作流字段列表
     * @param fieldMap       字段ID到字段实体的映射
     * @param moduleFieldMap 模块字段关联映射
     * @param moduleId       模块ID
     * @return 字段树列表
     */
    private List<ContractTemplateRespDTO.TemplateFieldTreeDTO> buildFieldTree(
            List<ContractWorkflowFormFieldEntity> workflowFields,
            Map<Integer, ContractFieldEntity> fieldMap,
            Map<String, ContractModuleFieldEntity> moduleFieldMap,
            Integer moduleId) {

        List<ContractTemplateRespDTO.TemplateFieldTreeDTO> result = new ArrayList<>();

        // 按字段ID分组工作流字段
        Map<Long, ContractWorkflowFormFieldEntity> workflowFieldMap = workflowFields.stream()
                .collect(Collectors.toMap(ContractWorkflowFormFieldEntity::getFieldId, wf -> wf));

        // 获取所有字段，并按父子关系分组
        List<ContractFieldEntity> allFields = workflowFields.stream()
                .map(wf -> fieldMap.get(wf.getFieldId()))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 分离父字段和子字段
        Map<Long, List<ContractFieldEntity>> parentChildMap = allFields.stream()
                .filter(field -> field.getParentFieldId() != null)
                .collect(Collectors.groupingBy(ContractFieldEntity::getParentFieldId));

        // 获取父字段（没有父字段ID的字段）
        List<ContractFieldEntity> parentFields = allFields.stream()
                .filter(field -> field.getParentFieldId() == null)
                .sorted((f1, f2) -> {
                    ContractWorkflowFormFieldEntity wf1 = workflowFieldMap.get(f1.getId());
                    ContractWorkflowFormFieldEntity wf2 = workflowFieldMap.get(f2.getId());
                    if (wf1 == null || wf2 == null) {
                        return 0;
                    }
                    return wf1.getFieldOrder().compareTo(wf2.getFieldOrder());
                })
                .collect(Collectors.toList());

        // 构建父字段树
        for (ContractFieldEntity parentField : parentFields) {
            ContractTemplateRespDTO.TemplateFieldTreeDTO parentFieldDTO =
                    convertToTemplateFieldTreeDTO(parentField, workflowFieldMap.get(parentField.getId()),
                            moduleFieldMap.get(moduleId + "_" + parentField.getId()));

            // 处理子字段
            List<ContractFieldEntity> childFields = parentChildMap.get(parentField.getId());
            if (!CollectionUtils.isEmpty(childFields)) {
                List<ContractTemplateRespDTO.TemplateFieldTreeDTO> childFieldDTOs =
                        childFields.stream()
                                .filter(child -> workflowFieldMap.containsKey(child.getId())) // 只包含工作流中的字段
                                .sorted((f1, f2) -> {
                                    ContractWorkflowFormFieldEntity wf1 = workflowFieldMap.get(f1.getId());
                                    ContractWorkflowFormFieldEntity wf2 = workflowFieldMap.get(f2.getId());
                                    if (wf1 == null || wf2 == null) {
                                        return 0;
                                    }
                                    return wf1.getFieldOrder().compareTo(wf2.getFieldOrder());
                                })
                                .map(child -> convertToTemplateFieldTreeDTO(child, workflowFieldMap.get(child.getId()),
                                        moduleFieldMap.get(moduleId + "_" + child.getId())))
                                .collect(Collectors.toList());
                parentFieldDTO.setChildren(childFieldDTOs);
            }

            result.add(parentFieldDTO);
        }

        return result;
    }

    /**
     * 构建包含group字段子字段的字段树
     *
     * @param workflowFields 工作流字段列表
     * @param fieldMap       字段ID到字段实体的映射（包含group字段的所有子字段）
     * @param moduleFieldMap 模块字段关联映射
     * @param moduleId       模块ID
     * @return 字段树列表
     */
    private List<ContractTemplateRespDTO.TemplateFieldTreeDTO> buildFieldTreeWithGroupChildren(
            List<ContractWorkflowFormFieldEntity> workflowFields,
            Map<Long, ContractFieldEntity> fieldMap,
            Map<String, ContractModuleFieldEntity> moduleFieldMap,
            Integer moduleId) {

        List<ContractTemplateRespDTO.TemplateFieldTreeDTO> result = new ArrayList<>();

        // 按字段ID分组工作流字段
        Map<Long, ContractWorkflowFormFieldEntity> workflowFieldMap = workflowFields.stream()
                .collect(Collectors.toMap(ContractWorkflowFormFieldEntity::getFieldId, wf -> wf));

        // 获取工作流中配置的字段
        List<ContractFieldEntity> workflowConfiguredFields = workflowFields.stream()
                .map(wf -> fieldMap.get(wf.getFieldId()))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 识别group类型字段并收集其所有子字段
        Set<Long> allRelevantFieldIds = new HashSet<>();
        List<ContractFieldEntity> allRelevantFields = new ArrayList<>();
        Set<Long> processedGroupIds = new HashSet<>(); // 防止重复处理group字段

        for (ContractFieldEntity field : workflowConfiguredFields) {
            if (!allRelevantFieldIds.contains(field.getId())) {
                allRelevantFieldIds.add(field.getId());
                allRelevantFields.add(field);
            }

            // 如果是group类型字段，添加其所有子字段
            if ("GROUP".equals(field.getFieldType()) && !processedGroupIds.contains(field.getId())) {
                processedGroupIds.add(field.getId());

                // 只从fieldMap中查找属于当前group的子字段
                List<ContractFieldEntity> groupChildren = fieldMap.values().stream()
                        .filter(f -> Objects.equals(f.getParentFieldId(), field.getId()))
                        .distinct() // 去重
                        .collect(Collectors.toList());

                for (ContractFieldEntity child : groupChildren) {
                    if (!allRelevantFieldIds.contains(child.getId())) {
                        allRelevantFieldIds.add(child.getId());
                        allRelevantFields.add(child);
                    }
                }
            }
        }

        // 按父子关系分组所有相关字段
        Map<Long, List<ContractFieldEntity>> parentChildMap = allRelevantFields.stream()
                .filter(field -> field.getParentFieldId() != null)
                .collect(Collectors.groupingBy(ContractFieldEntity::getParentFieldId));


        // 获取父字段（没有父字段ID的字段）
        List<ContractFieldEntity> parentFields = allRelevantFields.stream()
                .filter(field -> field.getParentFieldId() == null)
                .sorted((f1, f2) -> {
                    ContractWorkflowFormFieldEntity wf1 = workflowFieldMap.get(f1.getId());
                    ContractWorkflowFormFieldEntity wf2 = workflowFieldMap.get(f2.getId());
                    if (wf1 == null || wf2 == null) {
                        return 0;
                    }
                    return wf1.getFieldOrder().compareTo(wf2.getFieldOrder());
                })
                .collect(Collectors.toList());


        // 构建父字段树
        for (ContractFieldEntity parentField : parentFields) {
            // 检查父字段是否在工作流配置中
            ContractWorkflowFormFieldEntity parentWorkflowField = workflowFieldMap.get(parentField.getId());

            // 只处理在工作流中配置的字段或GROUP类型字段
            if (parentWorkflowField != null || "GROUP".equals(parentField.getFieldType())) {
                ContractTemplateRespDTO.TemplateFieldTreeDTO parentFieldDTO =
                        convertToTemplateFieldTreeDTO(parentField, parentWorkflowField,
                                moduleFieldMap.get(moduleId + "_" + parentField.getId()));

                // 处理子字段
                List<ContractFieldEntity> childFields = parentChildMap.get(parentField.getId());
                if (!CollectionUtils.isEmpty(childFields)) {
                    List<ContractTemplateRespDTO.TemplateFieldTreeDTO> childFieldDTOs = new ArrayList<>();
                    Set<Long> addedChildIds = new HashSet<>(); // 防止重复添加

                    for (ContractFieldEntity child : childFields) {
                        // 防止重复添加同一个子字段
                        if (addedChildIds.contains(child.getId())) {
                            continue;
                        }

                        // 检查子字段是否在当前模块中
                        String moduleFieldKey = moduleId + "_" + child.getId();
                        if (moduleFieldMap.containsKey(moduleFieldKey)) {
                            ContractWorkflowFormFieldEntity childWorkflowField = workflowFieldMap.get(child.getId());

                            // 如果子字段没有工作流配置（例如group字段的子字段），创建默认配置
                            if (childWorkflowField == null && "GROUP".equals(parentField.getFieldType())) {
                                childWorkflowField = createDefaultWorkflowField(child.getId(), moduleId);
                            }

                            if (childWorkflowField != null) {
                                ContractTemplateRespDTO.TemplateFieldTreeDTO childFieldDTO =
                                        convertToTemplateFieldTreeDTO(child, childWorkflowField,
                                                moduleFieldMap.get(moduleFieldKey));
                                childFieldDTOs.add(childFieldDTO);
                                addedChildIds.add(child.getId());
                            }
                        }
                    }

                    // 对子字段排序
                    childFieldDTOs.sort((f1, f2) -> {
                        Integer order1 = f1.getFieldOrder() != null ? f1.getFieldOrder() : 999;
                        Integer order2 = f2.getFieldOrder() != null ? f2.getFieldOrder() : 999;
                        return order1.compareTo(order2);
                    });

                    parentFieldDTO.setChildren(childFieldDTOs);
                }

                result.add(parentFieldDTO);
            }
        }

        return result;
    }

    /**
     * 为group字段的子字段创建默认的工作流字段配置
     *
     * @param fieldId  字段ID
     * @param moduleId 模块ID
     * @return 默认的工作流字段配置
     */
    private ContractWorkflowFormFieldEntity createDefaultWorkflowField(Long fieldId, Integer moduleId) {
        ContractWorkflowFormFieldEntity defaultField = new ContractWorkflowFormFieldEntity();
        defaultField.setFieldId(fieldId);
        defaultField.setModuleId(moduleId);
        defaultField.setIsRequired(false);
        defaultField.setFieldOrder(999); // 设置较大的排序值，放在最后
        defaultField.setIsHidden(false); // 不隐藏
        defaultField.setIsEnabled(true); // 可用
        defaultField.setIsDeleted(false); // 未删除
        return defaultField;
    }

    /**
     * 转换字段实体为模版字段树DTO
     *
     * @param field         字段实体
     * @param workflowField 工作流字段实体
     * @param moduleField   模块字段关联实体
     * @return 模版字段树DTO
     */
    private ContractTemplateRespDTO.TemplateFieldTreeDTO convertToTemplateFieldTreeDTO(
            ContractFieldEntity field,
            ContractWorkflowFormFieldEntity workflowField,
            ContractModuleFieldEntity moduleField) {

        ContractTemplateRespDTO.TemplateFieldTreeDTO fieldDTO =
                new ContractTemplateRespDTO.TemplateFieldTreeDTO();

        // 复制字段基本信息
        fieldDTO.setFieldId(field.getId());
        fieldDTO.setParentFieldId(field.getParentFieldId());
        fieldDTO.setFieldName(field.getFieldName());
        fieldDTO.setFieldType(field.getFieldType());
        fieldDTO.setFieldOptions(field.getFieldOptions());
        fieldDTO.setFieldDescription(field.getFieldDescription());
        fieldDTO.setIsRequired(field.getIsRequired());
        fieldDTO.setIsEnabled(field.getIsEnabled());
        fieldDTO.setIsSystem(field.getIsSystem());
        fieldDTO.setDecimalPlaces(field.getDecimalPlaces());
        fieldDTO.setUnit(field.getUnit());

        // 设置工作流相关信息
        if (workflowField != null) {
            fieldDTO.setFieldOrder(workflowField.getFieldOrder());
            fieldDTO.setIsHidden(workflowField.getIsHidden());
            // 如果工作流字段有特殊的必填设置，使用工作流的设置
            if (workflowField.getIsRequired() != null) {
                fieldDTO.setIsRequired(workflowField.getIsRequired());
            }
        }

        // 设置模块字段关联信息
        if (moduleField != null) {
            // 可以根据需要设置其他信息
        }

        // 初始化子字段列表
        fieldDTO.setChildren(new ArrayList<>());

        return fieldDTO;
    }

    /**
     * 根据合同类型获取模版内容
     *
     * @param template 合同模版实体
     * @return 模版内容
     */
    private String getTemplateContentByContractType(ContractTemplateEntity template) {
        try {
            // 1. 获取合同模版的最深层级合同类型ID
            Integer contractTypeId = getTemplateDeepestContractTypeId(template);
            if (contractTypeId == null) {
                log.info("合同模版没有设置合同类型，模版ID: {}", template.getTemplateId());
                return null;
            }

            // 2. 根据合同类型ID在contract_workflow_type表查找workflowId，并选择优先级最高的
            List<ContractWorkflowTypeEntity> workflowTypes = contractWorkflowTypeService.list(
                    new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                            .eq(ContractWorkflowTypeEntity::getContractTypeId, contractTypeId)
            );

            if (CollectionUtils.isEmpty(workflowTypes)) {
                log.info("未找到合同类型对应的工作流，合同类型ID: {}", contractTypeId);
                return null;
            }

            // 获取所有workflowId
            List<Long> workflowIds = workflowTypes.stream()
                    .map(ContractWorkflowTypeEntity::getWorkflowId)
                    .collect(Collectors.toList());

            // 查询所有对应的工作流，并选择优先级最高的（已发布的）
            List<ContractWorkflowEntity> workflows = contractWorkflowService.list(
                    new LambdaQueryWrapper<ContractWorkflowEntity>()
                            .in(ContractWorkflowEntity::getId, workflowIds)
                            .eq(ContractWorkflowEntity::getIsEnabled, true)
                            .orderByDesc(ContractWorkflowEntity::getPriority)
            );

            if (CollectionUtils.isEmpty(workflows)) {
                log.info("未找到已发布的工作流，合同类型ID: {}", contractTypeId);
                return null;
            }

            // 选择优先级最高的工作流
            ContractWorkflowEntity selectedWorkflow = workflows.get(0);
            Long workflowId = selectedWorkflow.getId();

            // 3. 获取工作流的processKey
            if (selectedWorkflow.getProcessKey() == null) {
                log.info("工作流没有关联流程，工作流ID: {}", workflowId);
                return null;
            }

            String processKey = selectedWorkflow.getProcessKey();

            // 根据processKey查找process_version最高的流程记录
            FlwProcess flwProcess = flwProcessMapper.selectOne(
                    new LambdaQueryWrapper<FlwProcess>()
                            .eq(FlwProcess::getProcessKey, processKey)
                            .orderByDesc(FlwProcess::getProcessVersion)
                            .last("LIMIT 1")
            );

            if (flwProcess == null) {
                log.info("未找到流程，流程key: {}", processKey);
                return null;
            }

            Long processId = flwProcess.getId();
            log.info("找到流程，流程key: {}, 版本: {}, processId: {}", processKey, flwProcess.getProcessVersion(), processId);

            // 4. 根据processId在flw_process_configure表查找process_form字段
            FlwProcessConfigure processConfigure = flwProcessConfigureService.getByProcessId(processId);
            if (processConfigure == null || processConfigure.getProcessForm() == null) {
                log.info("未找到流程配置或流程表单配置，流程processId: {}", processId);
                return null;
            }

            // 5. 解析process_form JSON，获取formId
            String processForm = processConfigure.getProcessForm();
            String formId = null;
            try {
                Map<String, Object> formMap = JSON.parseObject(processForm, Map.class);
                if (formMap != null && formMap.containsKey("formId")) {
                    formId = (String) formMap.get("formId");
                }
            } catch (Exception e) {
                log.warn("解析process_form JSON失败，processId: {}, processForm: {}", processId, processForm, e);
            }

            if (formId == null) {
                log.info("未能从process_form中解析出formId，流程ID: {}", processId);
                return null;
            }

            Long formIdLong;
            try {
                formIdLong = Long.parseLong(formId);
            } catch (NumberFormatException e) {
                log.warn("formId格式错误，无法转换为Long，formId: {}", formId);
                return null;
            }

            // 6. 根据解析出的formId在flw_form_template表中查询content
            FlwFormTemplate formTemplate = flwFormTemplateService.getById(formIdLong);
            if (formTemplate == null) {
                log.info("未找到表单模版，formId: {}", formIdLong);
                return null;
            }

            log.info("成功获取模版内容，模版ID: {}, formId: {}", template.getTemplateId(), formIdLong);
            return formTemplate.getContent();

        } catch (Exception e) {
            log.error("获取模版内容失败，模版ID: {}", template.getTemplateId(), e);
            return null;
        }
    }

    @Override
    public ContractFormDataDTO getContentByContractTypeAndDepartment(Integer contractTypeId) {
        // 获取当前用户的主部门ID
        UserInfo currentUser = AuthUtil.getCurrentUser();
        Long userDepartmentId = null;
        if (currentUser != null) {
            userDepartmentId = sysUserDepartmentService.getMainDepartmentIdByUserId(currentUser.getId());
        }
        return getContentByContractTypeAndDepartment(contractTypeId, userDepartmentId);
    }

    /**
     * 根据合同类型ID和部门ID获取模板content
     */
    public ContractFormDataDTO getContentByContractTypeAndDepartment(Integer contractTypeId, Long departmentId) {
        return getContentByContractTypeAndDepartment(contractTypeId, departmentId, null);
    }

    /**
     * 根据合同类型ID和部门ID获取模板content，并可选择保存processKey到模板
     */
    public ContractFormDataDTO getContentByContractTypeAndDepartment(Integer contractTypeId, Long departmentId, Integer templateId) {
        try {
            // 1. 验证合同类型是否存在
            ContractTypeEntity contractType = contractTypeMapper.selectById(contractTypeId);
            if (contractType == null) {
                throw new IllegalArgumentException("合同类型不存在，ID: " + contractTypeId);
            }

            log.info("合同模板流程匹配 - 只根据合同类型匹配，不考虑部门。合同类型ID: {}", contractTypeId);

            // 2. 根据合同类型ID在contract_workflow_type表查找workflowId
            List<ContractWorkflowTypeEntity> workflowTypes = contractWorkflowTypeService.list(
                    new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                            .eq(ContractWorkflowTypeEntity::getContractTypeId, contractTypeId)
            );

            if (CollectionUtils.isEmpty(workflowTypes)) {
                log.warn("未找到合同类型对应的工作流，合同类型ID: {}", contractTypeId);
                ApiAssert.fail(ResponseCodeEnum.NOT_FOUND_FLOW);

            }

            // 3. 获取所有workflowId
            List<Long> workflowIds = workflowTypes.stream()
                    .map(ContractWorkflowTypeEntity::getWorkflowId)
                    .collect(Collectors.toList());

            log.info("找到 {} 个候选工作流ID: {}", workflowIds.size(), workflowIds);

            // 4. 查询所有对应的工作流（已启用的），按优先级排序，不再考虑部门匹配
            List<ContractWorkflowEntity> allWorkflows = contractWorkflowService.list(
                    new LambdaQueryWrapper<ContractWorkflowEntity>()
                            .in(ContractWorkflowEntity::getId, workflowIds)
                            .eq(ContractWorkflowEntity::getIsEnabled, true)
                            .orderByDesc(ContractWorkflowEntity::getPriority)
            );

            if (CollectionUtils.isEmpty(allWorkflows)) {
                log.info("未找到已启用的工作流，合同类型ID: {}", contractTypeId);
                return null;
            }

            // 5. 直接选择优先级最高的工作流（不再考虑部门匹配）
            ContractWorkflowEntity selectedWorkflow = allWorkflows.get(0);
            log.info("选择工作流: ID={}, 名称={}, 优先级={}, ProcessKey={}",
                    selectedWorkflow.getId(), selectedWorkflow.getWorkflowName(),
                    selectedWorkflow.getPriority(), selectedWorkflow.getProcessKey());

            // 6. 获取工作流的processKey
            if (selectedWorkflow.getProcessKey() == null) {
                log.info("工作流没有关联流程，工作流ID: {}", selectedWorkflow.getId());
                return null;
            }

            String processKey = selectedWorkflow.getProcessKey();

            // 7. 根据processKey查找process_version最高的流程记录
            FlwProcess flwProcess = flwProcessMapper.selectOne(
                    new LambdaQueryWrapper<FlwProcess>()
                            .eq(FlwProcess::getProcessKey, processKey)
                            .orderByDesc(FlwProcess::getProcessVersion)
                            .last("LIMIT 1")
            );

            if (flwProcess == null) {
                log.info("未找到流程，流程key: {}", processKey);
                return null;
            }

            Long processId = flwProcess.getId();
            log.info("成功匹配合同模板流程，合同类型ID: {}, 工作流ID: {}, 优先级: {}, 流程key: {}, 版本: {}, processId: {}",
                    contractTypeId, selectedWorkflow.getId(), selectedWorkflow.getPriority(),
                    processKey, flwProcess.getProcessVersion(), processId);

            // 8. 根据processId在flw_process_configure表查找process_form字段
            FlwProcessConfigure processConfigure = flwProcessConfigureService.getByProcessId(processId);
            if (processConfigure == null || processConfigure.getProcessForm() == null) {
                log.info("未找到流程配置或流程表单配置，流程processId: {}", processId);
                return null;
            }

            // 9. 解析process_form JSON，获取formId
            String processForm = processConfigure.getProcessForm();
            String formId = null;
            try {
                Map<String, Object> formMap = JSON.parseObject(processForm, Map.class);
                if (formMap != null && formMap.containsKey("formId")) {
                    formId = (String) formMap.get("formId");
                }
            } catch (Exception e) {
                log.warn("解析process_form JSON失败，processId: {}, processForm: {}", processId, processForm, e);
            }

            if (formId == null) {
                log.info("未能从process_form中解析出formId，流程ID: {}", processId);
                return null;
            }

            Long formIdLong;
            try {
                formIdLong = Long.parseLong(formId);
            } catch (NumberFormatException e) {
                log.warn("formId格式错误，无法转换为Long，formId: {}", formId);
                return null;
            }

            // 10. 根据解析出的formId在flw_form_template表中查询content
            FlwFormTemplate formTemplate = flwFormTemplateService.getById(formIdLong);
            if (formTemplate == null) {
                log.info("未找到表单模版，formId: {}", formIdLong);
                return null;
            }

            String schemaContent = formTemplate.getContent();
            if (schemaContent == null) {
                log.warn("表单模版content为空，formId: {}", formIdLong);
                return null;
            }

            // 11. 如果提供了templateId，则保存processKey到模板中（只在processKey为空时保存）
            if (templateId != null) {
                try {
                    ContractTemplateEntity template = contractTemplateMapper.selectById(templateId);
                    if (template != null) {
                        // 只在模板的processKey为空时才设置，不覆盖已有的processKey
                        if (template.getProcessKey() == null) {
                            template.setProcessKey(processKey);
                            template.setUpdatedAt(LocalDateTime.now());
                            contractTemplateMapper.updateById(template);
                            log.info("成功保存processKey到模板，模板ID: {}, processKey: {}", templateId, processKey);
                        } else {
                            log.info("模板已有processKey，不覆盖，模板ID: {}, 已有processKey: {}, 当前processKey: {}",
                                    templateId, template.getProcessKey(), processKey);
                        }
                    } else {
                        log.warn("模板不存在，无法保存processKey，模板ID: {}", templateId);
                    }
                } catch (Exception e) {
                    log.error("保存processKey到模板失败，模板ID: {}, processKey: {}", templateId, processKey, e);
                }
            }

            // 12. 构建ContractFormDataDTO对象（与模板列表逻辑一致）
            ContractFormDataDTO formDataDTO = buildTemplateFormData(schemaContent);

            log.info("成功获取合同类型content，合同类型ID: {}", contractTypeId);

            return formDataDTO;
            
        } catch (Exception e) {
            log.error("根据合同类型获取content失败，合同类型ID: {}", contractTypeId, e);
            throw new RuntimeException("获取模板内容失败: " + e.getMessage(), e);
        }
    }

    /**
     * 根据主部门筛选工作流，只使用主部门进行匹配
     *
     * @param workflows 候选工作流列表（已按优先级排序）
     * @param mainDepartmentId 主部门ID
     * @param userId 用户ID
     * @return 匹配的工作流，如果没有匹配则返回null
     */
    private ContractWorkflowEntity findWorkflowByDepartment(List<ContractWorkflowEntity> workflows, Long mainDepartmentId, Long userId) {
        try {
            log.info("开始根据主部门筛选工作流，主部门ID: {}, 候选工作流数量: {}", mainDepartmentId, workflows.size());
            
            // 只使用主部门匹配，如果主部门没有匹配的工作流就直接返回null
            ContractWorkflowEntity mainDeptWorkflow = findWorkflowForSpecificDepartment(workflows, mainDepartmentId);
            if (mainDeptWorkflow != null) {
                log.info("主部门匹配成功，部门ID: {}, 工作流ID: {}", mainDepartmentId, mainDeptWorkflow.getId());
                return mainDeptWorkflow;
            }
            
            log.info("主部门无匹配工作流，不再尝试其他部门，主部门ID: {}", mainDepartmentId);
            return null;
            
        } catch (Exception e) {
            log.error("根据主部门筛选工作流失败，主部门ID: {}, 用户ID: {}", mainDepartmentId, userId, e);
            return null;
        }
    }
    
    /**
     * 为指定部门查找匹配的工作流
     *
     * @param workflows 候选工作流列表（已按优先级排序）
     * @param departmentId 部门ID
     * @return 匹配的工作流，如果没有匹配则返回null
     */
    private ContractWorkflowEntity findWorkflowForSpecificDepartment(List<ContractWorkflowEntity> workflows, Long departmentId) {
        try {
            // 检查该部门是否关联了工作流
            for (ContractWorkflowEntity workflow : workflows) {
                // 查询工作流是否适用于指定部门
                long departmentMatchCount = contractWorkflowDepartmentService.count(
                        new LambdaQueryWrapper<ContractWorkflowDepartment>()
                                .eq(ContractWorkflowDepartment::getWorkflowId, workflow.getId())
                                .eq(ContractWorkflowDepartment::getDepartmentId, departmentId)
                );
                
                if (departmentMatchCount > 0) {
                    log.info("找到部门匹配的工作流，部门ID: {}, 工作流ID: {}, 优先级: {}", 
                            departmentId, workflow.getId(), workflow.getPriority());
                    return workflow;
                }
            }
            
            log.debug("部门无匹配工作流，部门ID: {}", departmentId);
            return null;
            
        } catch (Exception e) {
            log.error("为部门查找工作流失败，部门ID: {}", departmentId, e);
            return null;
        }
    }
    
    /**
     * 上传空白Word文档到模版文件夹
     * 
     * @param currentUser 当前用户
     * @return 文件上传结果
     */
    private SingleResponse<FileUploadVO> uploadBlankWordDocument(UserInfo currentUser) {
        try {
            // 从classpath读取空白Word文档
            ClassPathResource resource = new ClassPathResource("static/documents/空白文稿.docx");
            
            if (!resource.exists()) {
                log.error("空白Word文档文件不存在：static/documents/空白文稿.docx");
                return SingleResponse.failure(500, "空白Word文档文件不存在");
            }
            
            // 读取文件内容
            InputStream inputStream = resource.getInputStream();
            byte[] fileBytes = inputStream.readAllBytes();
            inputStream.close();
            
            // 创建自定义MultipartFile对象
            MultipartFile multipartFile = new CustomMultipartFile(
                    "空白文稿.docx",
                    "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 
                    fileBytes
            );
            
            // 调用文件上传服务，上传到模版文件夹(文件夹类型5)
            SingleResponse<FileUploadVO> uploadResult = fileInfoService.fileUpload(multipartFile, 5, currentUser);
            
            log.info("空白Word文档上传结果: success={}, message={}", 
                    uploadResult.isSuccess(), uploadResult.getMessage());
            
            return uploadResult;
            
        } catch (IOException e) {
            log.error("读取空白Word文档时发生IO异常", e);
            return SingleResponse.failure(500, "读取空白Word文档失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("上传空白Word文档时发生异常", e);
            return SingleResponse.failure(500, "上传空白Word文档失败: " + e.getMessage());
        }
    }
    
    /**
     * 自定义MultipartFile实现，用于内部文件上传
     */
    private static class CustomMultipartFile implements MultipartFile {
        private final String originalFilename;
        private final String contentType;
        private final byte[] content;
        
        public CustomMultipartFile(String originalFilename, String contentType, byte[] content) {
            this.originalFilename = originalFilename;
            this.contentType = contentType;
            this.content = content;
        }
        
        @Override
        public String getName() {
            return "file";
        }
        
        @Override
        public String getOriginalFilename() {
            return originalFilename;
        }
        
        @Override
        public String getContentType() {
            return contentType;
        }
        
        @Override
        public boolean isEmpty() {
            return content == null || content.length == 0;
        }
        
        @Override
        public long getSize() {
            return content == null ? 0 : content.length;
        }
        
        @Override
        public byte[] getBytes() throws IOException {
            return content;
        }
        
        @Override
        public InputStream getInputStream() throws IOException {
            return new java.io.ByteArrayInputStream(content);
        }
        
        @Override
        public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
            try (java.io.FileOutputStream fos = new java.io.FileOutputStream(dest)) {
                fos.write(content);
            }
        }
    }
}